10分钟学会React Context API
Create-react-app来学习这个功能: 注意下面代码红色的即可,非常简单.
在小项目里Context API完全可以替换掉react-redux.
修改app.js
import React, { lazy, useState } from "react";
import { Button } from 'antd';
import { HashRouter as Router, Route, Link } from 'react-router-dom';
import GlobalContext from './globalContext' // 导入全局context
import './App.css';
//import Hehe from './hehe' //直接导入会让包变大,使用lazy会让包变小
const Hehe = lazy(() => import("./hehe"));
const T2 = lazy(() => import("./T2"));
const Reg = lazy(() => import(/* webpackChunkName: "reg" */'./reg'));
//普通的组件
const PageHeaderWrapper = (prop) => {
console.log("子组件刷新...");
return (
<>
<div>PageHeaderWrapper Memo:{prop.loading} {new Date().getTime()}</div>
<div>{prop.content}</div>
</>
)
}
// React.memo对PageHeaderWrapper组件进行包装,让这个PageHeaderWrapper组件进行包装组件变成可控组件
// React.memo()可接受2个参数,第一个参数为纯函数的组件,第二个参数用于对比props控制是否刷新,true不更新,与shouldComponentUpdate()功能类似。
const Memo = React.memo(PageHeaderWrapper, (prevProps, nextProps) => {
console.log(prevProps, nextProps);
//return true;
return prevProps.loading === nextProps.loading
}
);
//定义一个方法用来测试接受 Provider
const ChangeName = (props) => {
return (
<GlobalContext.Consumer>
{context =>
<div>{props.title}: {context.name}</div>
}
</GlobalContext.Consumer>
)
}
//产生一个随机内容的obj 只是为了示例使用
const rand = () => {
const a = parseInt(Math.random() * 4, 10);
return { name: "aaa" + a }
}
//入口文件
const App = () => {
const [value, setValue] = useState({ name: "aaa" });
return (
<GlobalContext.Provider value={value}>
<div className="App">
<header className="App-header">
<Memo loading={value.name} content='Memo content' />
<Button type="primary" onClick={() => setValue(rand)}>Hehe</Button>
<p>
Provider: {value.name}
</p>
<ChangeName title="changeName"></ChangeName>
<React.Suspense fallback="T2 loading...">
<Hehe />
</React.Suspense>
<Router>
<Link to="/reg">
<div>会员注册</div>
</Link>
<Link to="/t2">
<div>跳转到异步组件t2</div>
</Link>
<Route exact path='/' component={() => <React.Suspense fallback="T2 loading..."> <T2 /> </React.Suspense>} />
<Route path='/t2' component={() => <React.Suspense fallback="T2 loading..."> <T2 /> </React.Suspense>} />
<Route path='/reg' component={() => <React.Suspense fallback="Reg loading..."> <Reg /> </React.Suspense>} />
{/* <Route path='/regsync' component={Reg1} /> 使用同步组件会让包变大 */}
</Router>
</header>
</div>
</GlobalContext.Provider>
)
}
export default App;
reg.js
import React from "react"; import axios from "axios"; import { Form, Icon, Input, Button, Checkbox, Table } from 'antd'; const columns = [ { title: '姓名', dataIndex: 'name', key: 'name', }, { title: 'Email', dataIndex: 'email', key: 'email', }, { title: 'Ip', dataIndex: 'ip', key: 'ip', }, ]; //不要在使用class组件,使用函数式组件来,具体看T2.js class NormalLoginForm extends React.Component { constructor(props){ super(props) this.state = { dataSource:[] } } handleSubmit = e => { e.preventDefault(); //开始验证表单,如果原因 通过执行回调发送ajax this.props.form.validateFields((err, values) => { if (!err) { console.log('表单里的值: ', values); let request=values; request.test="test"; //向后台发送 axios.get("https://www.easy-mock.com/mock/5a3a2fc5ccd95b5cf43c5740/table_list",{ params: request }).then(response=>{ //后台返回的值: console.log(response.data); this.setState({dataSource:response.data.data}) }).catch(e=>{ //请求网络原因等失败了处理 }); } }); }; render() { const { getFieldDecorator } = this.props.form; return ( <div id="components-form-demo-normal-login"> <Form onSubmit={this.handleSubmit} className="login-form"> <Form.Item> {getFieldDecorator('username', { rules: [{ required: true, message: 'Please input your username!' }], })( <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="Username" />, )} </Form.Item> <Form.Item> {getFieldDecorator('password', { rules: [{ required: true, message: 'Please input your Password!' }], })( <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="Password" />, )} </Form.Item> <Form.Item> {getFieldDecorator('remember', { valuePropName: 'checked', initialValue: true, })(<Checkbox>Remember me</Checkbox>)} <Button type="primary" htmlType="submit" className="login-form-button"> Log in </Button> </Form.Item> </Form> <Table dataSource={this.state.dataSource} columns={columns} style={{background:'#fff'}} /> </div> ); } } const Reg = Form.create({ name: 'normal_login' })(NormalLoginForm); export default Reg;
T2.js
import React, {useState, useEffect} from "react";
import axios from "axios";
//组件 里可以使用state,这样就可以不在使用class
const T2=(prop)=>{
const [message, setMessage]=useState(()=>{
return 'start...';
});
function temp(){
axios.get('http://route.showapi.com/1764-1').then(response=> {
console.log(response.data.showapi_res_error);
setMessage(response.data.showapi_res_error);
})
}
useEffect( () => {
temp()
}, [message]);
// 给useEffect传第二个参数。用第二个参数来告诉react只有当这个参数的值发生改变时,才执行我们传的副作用函数(第一个参数)。
return (
<>
<div>T2. message: {message}</div>
</>
)
}
export default T2;
GlobalContext.js
import React from 'react' const GlobalContext = React.createContext(); export default GlobalContext;

浙公网安备 33010602011771号