1 组件通讯
1.1 props
子组件
import React from "react";
import PropTypes from "prop-types";
import { Button } from "antd";
export default class EightteenChildOne extends React.Component {
static propTypes = { //propTypes校验传入类型,详情在技巧11
name: PropTypes.string
};
click = () => {
// 通过触发方法子传父
this.props.eightteenChildOneToFather("这是 props 改变父元素的值");
};
render() {
return (
<div>
<div>这是通过 props 传入的值{this.props.name}</div>
<Button type="primary" onClick={this.click}>
点击改变父元素值
</Button>
</div>
);
}
}
复制代码
父组件
<EightteenChildOne name={'props 传入的 name 值'} eightteenChildOneToFather={(mode)=>this.eightteenChildOneToFather(mode)}></EightteenChildOne>
// 或者
<EightteenChildOne name={'props 传入的 name 值'} eightteenChildOneToFather={this.eightteenChildOneToFather.bind(this)}></EightteenChildOne>
复制代码
props 传多个值时:
传统写法
const {dataOne,dataTwo,dataThree} = this.state
<Com dataOne={dataOne} dataTwo={dataTwo} dataThree={dataThree}>
复制代码
升级写法
<Com {...{dataOne,dataTwo,dataThree}}>
复制代码
1.2 props 升级版
原理:子组件里面利用 props 获取父组件方法直接调用,从而改变父组件的值
注意: 此方法和 props 大同小异,都是 props 的应用,所以在源码中没有举例
调用父组件方法改变该值
// 父组件
state = {
count: {}
}
changeParentState = obj => {
this.setState(obj);
}
// 子组件
onClick = () => {
this.props.changeParentState({ count: 2 });
}
复制代码
1.3 Provider,Consumer和Context
1.Context在 16.x 之前是定义一个全局的对象,类似 vue 的 eventBus,如果组件要使用到该值直接通过this.context获取
//根组件
class MessageList extends React.Component {
getChildContext() {
return {color: "purple",text: "item text"};
}
render() {
const {messages} = this.props || {}
const children = messages && messages.map((message) =>
<Message text={message.text} />
);
return <div>{children}</div>;
}
}
MessageList.childContextTypes = {
color: React.PropTypes.string
text: React.PropTypes.string
};
//中间组件
class Message extends React.Component {
render() {
return (
<div>
<MessageItem />
<Button>Delete</Button>
</div>
);
}
}
//孙组件(接收组件)
class MessageItem extends React.Component {
render() {
return (
<div>
{this.context.text}
</div>
);
}
}
MessageItem.contextTypes = {
text: React.PropTypes.string //React.PropTypes在 15.5 版本被废弃,看项目实际的 React 版本
};
class Button extends React.Component {
render() {
return (
<button style={{background: this.context.color}}>
{this.props.children}
</button>
);
}
}
Button.contextTypes = {
color: React.PropTypes.string
};
复制代码
2.16.x 之后的Context使用了Provider和Customer模式,在顶层的Provider中传入value,在子孙级的Consumer中获取该值,并且能够传递函数,用来修改context 声明一个全局的 context 定义,context.js
import React from 'react'
let { Consumer, Provider } = React.createContext();//创建 context 并暴露Consumer和Provider模式
export {
Consumer,
Provider
}
复制代码
父组件导入
// 导入 Provider
import {Provider} from "../../utils/context"
<Provider value={name}>
<div style={{border:'1px solid red',width:'30%',margin:'50px auto',textAlign:'center'}}>
<p>父组件定义的值:{name}</p>
<EightteenChildTwo></EightteenChildTwo>
</div>
</Provider>
复制代码
子组件
// 导入Consumer
import { Consumer } from "../../utils/context"
function Son(props) {
return (
//Consumer容器,可以拿到上文传递下来的name属性,并可以展示对应的值
<Consumer>
{name => (
<div
style={{
border: "1px solid blue",
width: "60%",
margin: "20px auto",
textAlign: "center"
}}
>
// 在 Consumer 中可以直接通过 name 获取父组件的值
<p>子组件。获取父组件的值:{name}</p>
</div>
)}
</Consumer>
);
}
export default Son;
复制代码
1.4 EventEmitter
EventEmiter 传送门 使用 events 插件定义一个全局的事件机制
1.5 路由传参
1.params
<Route path='/path/:name' component={Path}/>
<link to="/path/2">xxx</Link>
this.props.history.push({pathname:"/path/" + name});
读取参数用:this.props.match.params.name
复制代码
2.query
<Route path='/query' component={Query}/>
<Link to={{ pathname : '/query' , query : { name : 'sunny' }}}>
this.props.history.push({pathname:"/query",query: { name : 'sunny' }});
读取参数用: this.props.location.query.name
复制代码
3.state
<Route path='/sort ' component={Sort}/>
<Link to={{ pathname : '/sort ' , state : { name : 'sunny' }}}>
this.props.history.push({pathname:"/sort ",state : { name : 'sunny' }});
读取参数用: this.props.location.query.state
复制代码
4.search
<Route path='/web/search ' component={Search}/>
<link to="web/search?id=12121212">xxx</Link>
this.props.history.push({pathname:`/web/search?id ${row.id}`});
读取参数用: this.props.location.search
复制代码
这个在 react-router-dom: v4.2.2有 bug,传参跳转页面会空白,刷新才会加载出来
5.优缺点
1.params在HashRouter和BrowserRouter路由中刷新页面参数都不会丢失
2.state在BrowserRouter中刷新页面参数不会丢失,在HashRouter路由中刷新页面会丢失
3.query:在HashRouter和BrowserRouter路由中刷新页面参数都会丢失
4.query和 state 可以传对象
本文章为自己学习的总结文章,文章参考于火狼1