React初学者经常从不需要获取数据的应用开始。他们经常面临一个计数器,任务列表获取井字棋游戏应用。这是很好的,因为在开始学习React的时候,数据获取在你的应用中添加了另一层复杂度。

然而,有些时候你想要从自己的或者第三方API请求真实世界的数据。这个文章给你一个怎么在React中获取数据的演练。这没有外部状态管理的解决方案,像Redux或者MobX参与存储你获取到的数据。相反你将要使用React的本地状态管理。

内容列表

  • 在React组件树的什么位置获取数据?
  • 如何在React中获取数据?
  • 怎么展示加载标识和处理错误呢?
  • 如何在React中使用Axios获取数据
  • 在React怎么测试数据获取?
  • 怎么在React中使用Async/Await获取数据?
  • 如何在高阶组件中获取数据?
  • 怎么在渲染属性里获取数据?
  • 在React中怎么从GraphQL获取数据?

在React组件树的什么位置获取数据?

想象你已经有一个组件树,在它的层级中有多个级别的组件。现在你将要从第三方API获取一个列表项。现在,在你组件级别的哪个等级,更精确的讲,哪个特定组件,应该获取数据?这个基本上取决于三个标准:

1.谁对这个数据感兴趣?获取数据的组件应该是这些组件的公共父组件。

1. Who is interested in this data? The fetching component should be a common parent component for all these components.

                      +---------------+|               ||               ||               ||               |+------+--------+|+---------+------------+|                      ||                      |+-------+-------+     +--------+------+|               |     |               ||               |     |               ||  Fetch here!  |     |               ||               |     |               |+-------+-------+     +---------------+|+-----------+----------+---------------------+|                      |                     ||                      |                     |
+------+--------+     +-------+-------+     +-------+-------+
|               |     |               |     |               |
|               |     |               |     |               |
|    I am!      |     |               |     |     I am!     |
|               |     |               |     |               |
+---------------+     +-------+-------+     +---------------+||||+-------+-------+|               ||               ||     I am!     ||               |+---------------+

2.当异步请求数据的时候你想在哪里展示一个加载标识(加载标志,进度条)? 根据第一个标准,这个加载标识可以展示在公共父组件中。然后这个公共父组件还是获取数据的组件。

                      +---------------+|               ||               ||               ||               |+------+--------+|+---------+------------+|                      ||                      |+-------+-------+     +--------+------+|               |     |               ||               |     |               ||  Fetch here!  |     |               ||  Loading ...  |     |               |+-------+-------+     +---------------+|+-----------+----------+---------------------+|                      |                     ||                      |                     |
+------+--------+     +-------+-------+     +-------+-------+
|               |     |               |     |               |
|               |     |               |     |               |
|    I am!      |     |               |     |     I am!     |
|               |     |               |     |               |
+---------------+     +-------+-------+     +---------------+||||+-------+-------+|               ||               ||     I am!     ||               |+---------------+

**2.1.**但是当加载标识需要在更高级的组件中,数据获取也需要被提升到这个组件中。

                      +---------------+|               ||               ||  Fetch here!  ||  Loading ...  |+------+--------+|+---------+------------+|                      ||                      |+-------+-------+     +--------+------+|               |     |               ||               |     |               ||               |     |               ||               |     |               |+-------+-------+     +---------------+|+-----------+----------+---------------------+|                      |                     ||                      |                     |
+------+--------+     +-------+-------+     +-------+-------+
|               |     |               |     |               |
|               |     |               |     |               |
|    I am!      |     |               |     |     I am!     |
|               |     |               |     |               |
+---------------+     +-------+-------+     +---------------+||||+-------+-------+|               ||               ||     I am!     ||               |+---------------+

2.2. 当加载标识应该在公共父组件的每个子组件展示,不是每个子组件都需要数据,公共父组件应该还是获取数据的组件。然后这个加载标识状态可以传下来给那些感兴趣,需要展示加载标识的子组件。

                      +---------------+|               ||               ||               ||               |+------+--------+|+---------+------------+|                      ||                      |+-------+-------+     +--------+------+|               |     |               ||               |     |               ||  Fetch here!  |     |               ||               |     |               |+-------+-------+     +---------------+|+-----------+----------+---------------------+|                      |                     ||                      |                     |
+------+--------+     +-------+-------+     +-------+-------+
|               |     |               |     |               |
|               |     |               |     |               |
|    I am!      |     |               |     |     I am!     |
|  Loading ...  |     |  Loading ...  |     |  Loading ...  |
+---------------+     +-------+-------+     +---------------+||||+-------+-------+|               ||               ||     I am!     ||               |+---------------+

**3. 当请求失败的时候,你想在哪里展示可选的错误信息?**这个和第二个加载标识的标准使用一样的规则。
这基本上就是在React组件层次结构中获取数据的所有内容。但是什么时候获应该取数据,一旦公共父组件达成一致应该如何获取数据?

如何在React中获取数据?

React的ES6类组件有生命周期方法。render()生命周期方法强制返回一个React元素,因为毕竟你可能想在某一点展示获取到的数据。

另一个生命周期方法是获取数据的完美选择:componentDidMount()。当这个方法执行的时候,这个组件已经通过render()方法渲染了一次,但是将会在获取数据并通过组件的setState()方法将数据存储在本地后再次渲染。之后,本地状态可以被render()方法使用去展示,或者通过props向下传递。

componentDidMount()生命周期方法是获取数据最好的地方。但是怎么去获取数据? React的生态系统是一个灵活的框架

从而你可以选择你自己的方法去获取数据。为了简单起见,这篇文章将会使用浏览器原生fetch API展示它。它使用了JavaScript promise作为异步函数的结果。这是获取数据的最小示例,像下面这样:

import React, { Component } from 'react';class App extends Component {constructor(props) {super(props);this.state = {data: null,};}componentDidMount() {fetch('https://api.mydomain.com').then(response => response.json()).then(data => this.setState({ data }));}...
}export default App;

这是一个最基本React.js fetch API的例子。这个例子向你展示了在React怎么从API中获取JSON。然而,这边文章将要演示怎么从一个真实世界中第三方API中获取数据。

import React, { Component } from 'react';// -----------------------------------
const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';
// -----------------------------------class App extends Component {constructor(props) {super(props);this.state = {// -----------------------------------hits: [],// -----------------------------------};}componentDidMount() {// -----------------------------------fetch(API + DEFAULT_QUERY)// -----------------------------------.then(response => response.json())// -----------------------------------.then(data => this.setState({ hits: data.hits }));// -----------------------------------}...
}export default App;

这个例子使用Hacker News API,但是你可以使用你自己的API。当数据获取成功,数据将通过React的 this.setState()方法被存在本地状态中。然后 render方法将再次触发并且你可以展示获取到的数据。

...class App extends Component {...render() {const { hits } = this.state;return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}
}export default App;

即使render()方法已经在 componentDidMount()方法之前执行过一次,你不会遇到任何空指针异常,因为你在本地状态里有一个初始的空数组hits属性。

**注意:**如果你想知道怎么通过React Hooks特性获取数据,查看这个全面的指南如何在ReactHooks中获取数据(翻译)

怎么展示加载标识和处理错误呢?

当然你需要获取数据到你本地状态。但是还有什么?这里还有两个属性你可以存储在状态里:加载状态和错误状态。这些将提升你应用的用户体验。

加载状态应该用于指示一个异步请求在进行中。在render()方法之间,由于异步到达,获取数据在等待中。从而你可以在等待期间添加一个加载标识。在你获取数据的生命周期方法里,你必须将这个属性从false切换到true,当数据被获取到应该从true切换到false。

...class App extends Component {constructor(props) {super(props);this.state = {hits: [],// -----------------------------------isLoading: false,// -----------------------------------};}componentDidMount() {// -----------------------------------this.setState({ isLoading: true });// -----------------------------------fetch(API + DEFAULT_QUERY).then(response => response.json())// -----------------------------------.then(data => this.setState({ hits: data.hits, isLoading: false }));// -----------------------------------}...
}export default App;

在你的render()方法里你可以使用React的条件渲染去展示加载标识或者加载到的数据。

...class App extends Component {...render() {// -----------------------------------const { hits, isLoading } = this.state;// -----------------------------------// -----------------------------------if (isLoading) {return <p>Loading ...</p>;}// -----------------------------------return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}
}

一个加载标识可以向Loading…消息一样简单,但是你也可以使用第三方库区展示一个标识或者待定组件内容。你可以通过信号通知用户数据提取正在等待中。

你可以保持在你本地的第二个状态将是一个错误状态。当你的应用中发生一个错误,没什么比不给用户关于错误的标识更差的了。

...class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,// -----------------------------------error: null,// -----------------------------------};}...}

使用promise的时候经常在then()后面使用catch()块去处理错误。这就是为什么可以在原生的fetch API上使用catch()块。

...class App extends Component {...componentDidMount() {this.setState({ isLoading: true });fetch(API + DEFAULT_QUERY).then(response => response.json()).then(data => this.setState({ hits: data.hits, isLoading: false }))// -----------------------------------.catch(error => this.setState({ error, isLoading: false }));// -----------------------------------}...}

不幸的是,这个原生的fetch API不能使用catch块捕获每个错误的状态码。例如,当一个HTTP 404 发生了,并不会执行到catch块里。但是当你没有在结果中匹配到你希望的数据时,你可以通过抛出一个错误强制执行到catch块。

...class App extends Component {...componentDidMount() {this.setState({ isLoading: true });fetch(API + DEFAULT_QUERY)// -----------------------------------.then(response => {if (response.ok) {return response.json();} else {throw new Error('Something went wrong ...');}})// -----------------------------------.then(data => this.setState({ hits: data.hits, isLoading: false })).catch(error => this.setState({ error, isLoading: false }));}...}

最后但也很重要的是,你可以再次通过条件渲染在你的render()方法展示一个错误消息。

...class App extends Component {...render() {// -----------------------------------const { hits, isLoading, error } = this.state;// -----------------------------------// -----------------------------------if (error) {return <p>{error.message}</p>;}// -----------------------------------if (isLoading) {return <p>Loading ...</p>;}return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}
}

这就是使用简单的React获取数据的基础知识。你可以阅读有关在React的本地状态中管理所获取数据的更多信息,或者在React中独自管理状态诸如Redux之类的库。

如何在React中使用Axios获取数据

就像已经提到的,你可以使用其它库替代原生的fetch API。例如,另一个库可能每一个错误的请求都会到catch块中,不需要你自己向原先那样抛出一个错误。一个获取数据好的选择是axios库。你可以通过npm install axios在你的项目中安装axios,然后在你的项目中使用它替代原生的fetch API。让我们使用axios取代原生的fetch API在React中获取数据重构上一个项目。

import React, { Component } from 'react';
// -----------------------------------
import axios from 'axios';
// -----------------------------------const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });// -----------------------------------axios.get(API + DEFAULT_QUERY).then(result => this.setState({hits: result.data.hits,// -----------------------------------isLoading: false})).catch(error => this.setState({error,isLoading: false}));}...
}export default App;

就像你看到的,axios也返回了一个JavaScript promise对象。但是现在你不能解决这个promise两次,因为axios已经给你返回了一个JSON响应。

此外,当使用axios你可以确定所有错误都会在catch()块被捕捉。另外,你需要略微调整axios返回的数据结构就行。

在上一个例子里向你展示了怎么在React的componentDidMount生命周期方法里通过一个HTTP的GET方法获取数据。然而,你也可以通过一个按钮的点击来触发请求。然后你不需要使用生命周期方法,但是你可以使用自己的类方法。

import React, { Component } from 'react';
import axios from 'axios';const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,error: null,};}// -----------------------------------getStories() {// -----------------------------------this.setState({ isLoading: true });axios.get(API + DEFAULT_QUERY).then(result => this.setState({hits: result.data.hits,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}...
}export default App;

但是这只是React里的GET方法的使用。怎么通过API写入数据?当使用axios的时候,你也可以在React发送一个post请求。你也需要将axios.get()换成axios.post()

在React怎么测试数据获取?

所以怎么在React组件中测试数据获取呢?这里有一个关于测试话题的广泛的React测试教程,当你使用create-react-app建立你的应用,它已经带来了Jest测试框架和断言库。除此之外你也可以使用Mocha(测试框架)和Chai(断言库)来实现这些目的(记住功能会因为测试框架和断言库而变化)

当测试React组件的时候,在我的测试用例中,我经常依赖Enzyme去渲染组件。此外,当测试异步数据获取,Sinon有助于检查和模拟数据。

npm install enzyme enzyme-adapter-react-16 sinon --save-dev

首先你有你的测试体系,你可以在React脚本中写你第一个数据获取的测试套件

import React from 'react';
import axios from 'axios';import sinon from 'sinon';
import { mount, configure} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';import App from './';configure({ adapter: new Adapter() });describe('App', () => {beforeAll(() => {});afterAll(() => {});it('renders data when it fetched data successfully', (done) => {});it('stores data in local state', (done) => {});
});

而一个测试用例应该在数据获取后在React组件成功渲染数据,提测测试用例验证数据被存储在本地状态里。或许测试两种情况是冗余的,因为当数据被渲染了,那么数据也应该被存在本地状态里了,但是只是为了展示,你会看到两个用例。

在所有测试之前,你希望使用模拟数据来存储您的axios请求。你可以为请求创建自己的JavaScript promise 并且之后可以使用它细腻的控制promise的解决。

...describe('App', () => {const result = {// -----------------------------------data: {hits: [{ objectID: '1', url: 'https://blog.com/hello', title: 'hello', },{ objectID: '2', url: 'https://blog.com/there', title: 'there', },],}};// -----------------------------------const promise = Promise.resolve(result);beforeAll(() => {// -----------------------------------sinon.stub(axios, 'get').withArgs('https://hn.algolia.com/api/v1/search?query=redux').returns(promise);// -----------------------------------});afterAll(() => {// -----------------------------------axios.get.restore();// -----------------------------------});...
});

在所有测试之后你应该再次确认移除了所有axios的存根。这句是异步数据获取测试的建立。现在让我们实现第一个测试:

...describe('App', () => {...it('stores data in local state', (done) => {const wrapper = mount(<App />);expect(wrapper.state().hits).toEqual([]);promise.then(() => {wrapper.update();expect(wrapper.state().hits).toEqual(result.data.hits);done();});});...
});

在测试中,你通过Enzyme的mount()函数开始渲染React组件,这个方法确保所有生命生命周期方法执行,并且所有子组件被渲染。

最初你可以在你组件本地状态的hit是一个空数组的时候有一个断言。这应该是正确的,因为你通过一个空数组初始化你的本地状态的hits属性。首先你解决了promise并且手动触发了组件的渲染,这个状态应该在数据获取后改变。

接下来,你可以测试所有内容是否相应呈现。这个测试和之前测试很像。

...describe('App', () => {...it('renders data when it fetched data successfully', (done) => {const wrapper = mount(<App />);expect(wrapper.find('p').text()).toEqual('Loading ...');promise.then(() => {wrapper.update();expect(wrapper.find('li')).toHaveLength(2);done();});});
});

在测试开始前,加载中标识应该被渲染。再次,一旦你解决了promise并且手动触发组件的渲染,应该有两个列表元素用于请求数据。

这些基本上就是React中关于数据获取测试你需要知道的。它不需要复杂。当有自己的promise,你可以精细控制合适解决promise和更新组件。之后你可以进行断言。之前展示的测试场景只是一个方法。例如,关于测试工具你不一定需要使用Sinon和Enzyme。

怎么在React中使用Async/Await获取数据?

至今,你只通过通用的方法then()catch()块去处理JavaScript promise。使用JavaScript中下一代异步请求怎么样?让我们使用async/await重构上一个数据获取的例子。

import React, { Component } from 'react';
import axios from 'axios';const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';class App extends Component {...// -----------------------------------async componentDidMount() {// -----------------------------------this.setState({ isLoading: true });// -----------------------------------try {const result = await axios.get(API + DEFAULT_QUERY);// -----------------------------------this.setState({hits: result.data.hits,isLoading: false});// -----------------------------------} catch (error) {// -----------------------------------this.setState({error,isLoading: false});// -----------------------------------}// -----------------------------------}...
}export default App;

当在React中获取数据的时候你可以使用async/await语句取代then()。async语句用于表示函数是异步执行的。它也可以使用在(React)类组件的方法上。await语句是在async函数内部每当执行异步函数时使用的。所以在等待的请求解决前下一行是不会执行的。此外,如果请求失败,一个try catch块可以用于捕获错误。

如何在高阶组件中获取数据?

在许多组件中使用它时,之前展示的获取数据的方法可以复用。一旦一个组件挂载,你想去获取数据并且展示条件加载标识和错误标识。这个组件入境可以分出两个职责:通过条件渲染展示获取到的数据和获取到远程数据之后存在本地状态里。而前者只用于渲染目的,后者可以通过高阶组件被重用。

注意:当你要去阅读链接的文章,你也将会看到你怎么在高阶组件中抽象条件渲染。在那之后,你的组件将只关心展示获取到的数据,没有任何条件渲染。

所以你怎样引入抽象高阶组件处理在React中的数据获取。首先你将会分离所有获取和存储逻辑到高阶组件中。

const withFetching = (url) => (Component) =>class WithFetching extends React.Component {constructor(props) {super(props);this.state = {data: null,isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });axios.get(url).then(result => this.setState({data: result.data,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}render() {return <Component { ...this.props } { ...this.state } />;}}

除了渲染,高阶组价中每个其他部分都取自上一个组件的数据正确提取的部分。另外,高阶组件使用接受到的一个url获取请求数据。如果你需要传递更多参数给告诫组件,你也可以扩展函数签名的参数列表。

const withFetching = (url, query) => (Comp) =>...

另外,告诫组件使用一个名叫data的通过用数据包裹本地状态。它不再像之前一样了解具体的属性名(e.g hits)

第二步,你可以部署所有来自你的App组件的数据获取和状态逻辑,因为它再也没有本地状态和生命周期方法。你可以通过函数式无状态组件重用它。传入的属性从特定命名改为通用数据属性。

const App = ({ data, isLoading, error }) => {if (!data) {return <p>No data yet ...</p>;}if (error) {return <p>{error.message}</p>;}if (isLoading) {return <p>Loading ...</p>;}return (<ul>{data.hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);
}

最后但也很重要的是,你可以使用高阶组件区包裹你的App组件。

const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';...const AppWithFetch = withFetching(API + DEFAULT_QUERY)(App);

基本上这就是在React中的抽离数据获取。通过使用告诫组件去获取数据,你可以轻松配置任何需要url获取数据的任何组件。另外,你可以扩展它通过查询参数就像之前展示过得。

#怎么在渲染属性里获取数据?

在React中可以在高阶组件和渲染属性里二选一。在React中使用渲染属性去数据获取也是可以的。

class Fetcher extends React.Component {constructor(props) {super(props);this.state = {data: null,isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });axios.get(this.props.url).then(result => this.setState({data: result.data,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}render() {return this.props.children(this.state);}
}

然后你可以再次向下面这样在你的App组件中使用渲染属性。

const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';...const RenderPropApproach = () =><Fetcher url={API + DEFAULT_QUERY}>{({ data, isLoading, error }) => {if (!data) {return <p>No data yet ...</p>;}if (error) {return <p>{error.message}</p>;}if (isLoading) {return <p>Loading ...</p>;}return (<ul>{data.hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}}</Fetcher>

通过使用React的children属性作为渲染苏醒,你也可以从Fetcher组件传递所有本地状态。这就是你让所有条件渲染和最终渲染在你的属性渲染中的办法。

在React中怎么从GraphQL获取数据?

最后但也很重要的是,这篇文章应该很快提到React的GraphQL API。在React组件中你怎么用使用GraphQL API取代REST API获取数据(如今你使用的是哪个)?基本上它可以以同样的方式实现,因为GraphQL对网络层没有要求。大多数GraphQL API都是通过HTTP公开的,无论是否使用原生的fetch API还是axios进行查询。如果你感兴趣在React中如何通过GraphQL API获取数据,前往这篇文章:A complete React with GraphQL Tutorial。

你可以在这个github仓库找到完成的项目。你还有对于React中数据获取的建议吗?请联系我。你将这篇文章分享给其他学习如何在React中获取数据的人对我很有意义。

在React中获取数据相关推荐

  1. usestate中的回调函数_React 中获取数据的 3 种方法:哪种最好?

    译文 | https://cloud.tencent.com/developer/article/1535913 原文 | https://dmitripavlutin.com/ 在执行 I/O 操作 ...

  2. 揭秘 React 异步获取数据的进化历程

    点击上方 前端瓶子君,关注公众号 回复算法,加入前端编程面试算法每日一题群 本篇文章,以模拟从『Hacker News API[1]』获取热门文章为例,通过一步步地代码优化和封装,阐述 React 异 ...

  3. OC从plist文件中获取数据

    怎样从plist文件中读取数据,这个和反归档相似,但是也存在着区别,比如说不用解码,当然一般我们获取的数据往往是对一个对象的描述,而且数据的个数也不是一个,因此我们有必要来说一下怎样完整的从plist ...

  4. C#从剪贴板中获取数据

    今天我们同学问我如何利用C#把剪贴板里的图片存出来,我看了看,非常简单 IDataObject data = Clipboard.GetDataObject();//从剪贴板中获取数据 if(data ...

  5. c从sqlite3数据库中获取数据,并对数据进行拼接

    c从sqlite3数据库中获取数据,并对数据进行拼接 函数功能 对数据库的操作 创建数据库: 创建USER表: 创建表内数据: 查看表内数据: 查看表结构: 函数实现 函数编译: 函数结果: 函数功能 ...

  6. ​​​​​​​​​​​​​​使用dom方式遍历文档||获取元素||从元素中获取数据

    使用dom方式遍历文档 获取元素 根据id查询元素getElementById 根据标签获取元素getElementsByTag 根据class获取元素getElementsByClass 根据属性获 ...

  7. getdata提取曲线数据_Origin如何从图表中获取数据

    点击上方"蓝字",一起愉快的玩耍吧!Origin如何从图表中获取数据01图片分析软件安装 一.GetData Graph Digitizer安装 使用范围: 1.需要引用别人文章中 ...

  8. Vue项目中获取数据后使用swiper轮播,无法轮播且 autoplay 和 loop 失效问题!

    Vue项目中获取数据后使用swiper轮播,无法轮播且 autoplay 和 loop 失效问题! 问题表现:轮播组件显示第一张图,可拖动但无法切换到下一张图.但是F12控制台切换屏幕后能正常轮播但无 ...

  9. python临床数据_从临床试验中获取数据

    我正在开发一个小Python函数来从clinicalTrials.gov中获取数据.从每个研究记录中,我想从中找出研究的目标条件.例如,对于this研究记录,我需要以下内容:conditions = ...

最新文章

  1. Leetcode 130. 被围绕的区域 解题思路及C++实现
  2. javaweb里边的重定向与转发的区别
  3. 批量获取远程计算机MAC
  4. 为什么启动hbase shell后,创建按create 'test', 'cf'失败?
  5. JDK1.8的新特性详解
  6. 循证e刊 安慰剂的前世今生
  7. 虚幻UE4的后处理特效介绍 http://www.52vr.com/thread-31215-1-1.html
  8. SPFA求最短路——Bellman-Ford算法的优化
  9. C++ 时间操作(获取毫秒级)【转】
  10. HDU 3350 #define is unsafe
  11. 搜索场 day1 A 求和
  12. DDOS高防IP作用,哪些地方需要用到高防IP
  13. Word解析之Word内部结构
  14. 在财务中python能做什么_Python在财务会计工作中的应用【举例】
  15. 世界上手机号码最长和最短的国家
  16. 计算机网络连接限制,网络连接受限,详细教您网络连接受限怎么解决
  17. 小米手机修改ip代理服务器,小米路由器3 IP地址更改方法【图文】
  18. 编写一个求和函数sum,用于计算 1+2+…+n ,在主函数调用该函数求和。
  19. jQuery之.each( function(index, Element) )
  20. SNAT与DNAT详解

热门文章

  1. python保存变量_将python 中的变量保存到本地
  2. java web登录状态保持_java web用于保持状态的4种方法
  3. 深入理解Python中的元类(metaclass)
  4. 《java从入门到精通》pdf
  5. 题目1065:输出梯形 (直接用循环控制输出)+题目1432:叠筐 (数组控制形状,最后输出数组)...
  6. 转载[POJ题型分类]
  7. 有一只猪400斤,桥承重200斤,怎么过桥?
  8. matlab中“存储空间不足,无法处理此命令”
  9. C语言sendto()函数:经socket传送数据
  10. 局域网共享问题全方位解决