React组件通信之打怪升级
Hello呀,我是樱乔。笔者很菜,如果有知识点理解错误的地方,请各位看官多多指教。
💕本周的内容是React组件间的通信。
一、组件通信(活化石版)
设置上下文信息
父组件:
childContextType——定义需要传递的属性数据类型
getChildContext()——返回对象就是context传递的属性
子组件:
contextTypes——定义子组件想要调用的属性数据类型
this.context——访问被contextTypes指定的父组件内容
class Complain extends React.Component {
static contextTypes = {
surface: PropTypes.string,
};
render() {
return <div>{this.context.surface}</div>;
}
}
class ComplainButton extends React.Component {
static contextTypes = {
realHeart: PropTypes.func,
};
render() {
return (
<>
<button
onClick={(ev) => {
this.context.realHeart("好难啊!学吐了~~~");
}}
>
真实想法
</button>
</>
);
}
}
export default class Father extends React.Component {
static childContextTypes = {
surface: PropTypes.string,
realHeart: PropTypes.func,
};
getChildContext() {
return {
surface: this.state.surface,
realHeart: this.realHeart,
};
}
state = { surface: "前端很简单的,加油哦!!!" };
realHeart = (myHeart) => {
this.setState({
surface: myHeart,
});
};
render() {
return (
<div>
<h3>来自小白的抱怨</h3>
<Complain />
<ComplainButton />
</div>
);
}
}
二、组件通信(老古董版)
React.createContext——React大神提供的API
父组件:
ThemeContext.Provider——父组件注册上下文中的内容
子组件:
ThemeContext.Consumer——子组件进行消费(即获取上下文中内容)
//创建上下文对象
let ThemeContext = React.createContext();
//这是子组件第一种调用方式哦
class Complain extends React.Component {
//将父组件提供的属性放在this.context中
static contextTypes = ThemeContext;
render() {
return <div>{this.context.surface}</div>;
}
}
//这是子组件第二种调用方式哟
class ComplainButton extends React.Component {
render() {
return (
<ThemeContext.Consumer>
{(context) => {
return (
<button
onClick={(ev) => {
context.realHeart("好难啊!学吐了~~~");
}}
>
真实想法
</button>
);
}}
</ThemeContext.Consumer>
);
}
}
export default class Father extends React.Component {
state = { surface: "前端很简单的,加油哦!!!" };
realHeart = (myHeart) => {
this.setState({
surface: myHeart,
});
};
//value传递上下文信息
render() {
return (
<ThemeContext.Provider
value={{
surface: this.state.surface,
realHeart: this.realHeart,
}}
>
<h3>来自小白的抱怨</h3>
<Complain />
<ComplainButton />
</ThemeContext.Provider>
);
}
}
三、组件通信(Redux版)
state——store容器中存储的当前状态
action——dispatch派发的行为对象
getState()——获取容器中的状态
subscribe([methods])——控制组件重新渲染(因此,该方法需要存储能重新渲染组件的方法)
reducer(state,action)——管理所有修改状态的操作
dispatch(action)——告知reducer修改状态
class Complain extends React.Component {
constructor(props) {
super(props);
this.state = {
...props.store.getState(),
};
}
componentDidMount() {
this.setState({
...this.props.store.getState(),
});
}
render() {
return <div>{this.state.surface}</div>;
}
}
class ComplainButton extends React.Component {
store = this.props.store;
render() {
return (
<button
onClick={(ev) => {
store.dispatch({
type: "MY_HEART",
surface: "好难啊!学吐了~~~",
});
}}
>
真实想法
</button>
);
}
}
export default class Father extends React.Component {
render() {
let store = this.props.store,
{ surface } = store.getState();
return (
<div>
<h3>来自小白的抱怨</h3>
<Complain store={store} />
<ComplainButton store={store} />
</div>
);
}
}
//index.js中调用
const reducer = function (
state = {
surface: "前端很简单的,加油哦!!!",
},
action
) {
state = JSON.parse(JSON.stringify(state));
let surface = action.surface;
switch (action.type) {
case "MY_HEART":
state.surface = surface;
break;
default:
break;
}
return state;
};
const store = createStore(reducer);
ReactDom.render(
<>
<Father store={store} />
</>,
document.getElementById("root")
);
四、组件通信(React-Redux版)
Provider作用
将容器中的store放置到上下文,供子组件调用
connect作用
(1)将state和action作为属性赋值给某一组件
(2)包含subsribe功能
(3)页面渲染的组件为connect返回的代理组件
与redux相比较,优化点如下
//1.Provider包裹
ReactDOM.render(<Provider store={store}>
<Vote />
</Provider>, document.getElementById('root'));
//2.connect封装
export default connect(state => ({...state.vote}), actions.vote)(Vote);
//=>第一个参数获取redux容器中的状态信息并挂载到组件属性上,通过props进行获取(this.props.father),相当于:
function mapStateToProps(state) {
return {
...state.father
};
}
//=>第二个参数将actions中的方法转换为派发格式,可以通过props直接调用方法完成派发任务(this.props.myHeart()),相当于:
function mapDispatchToProps(){
return {
myHeart(){
dispatch(actions.father.myHeart());
}
}
}
886~ 下周见🌼