如何将 Redux 连接到孙组件
介绍
大家好!在本指南中,我们将学习使用 Redux(React 的流行状态管理库)将数据从父组件传递到孙组件。
在构建 Web 应用时,您一定遇到过这样的情况:您必须将数据作为 props 从一个组件传递到另一个组件,几分钟后,您发现自己将 props 传递给了第 99 个后继组件(有点夸张,但您明白我的意思)。好吧,Redux 就是为此类场景而构建的。
包裹根组件
第一步是使用 Redux 的<Provider />组件包装应用程序的根组件。
<Provider />组件需要 store 对象。store 对象保存着应用程序的整个状态。
// ..
import { Provider } from "react-redux";
const App = () => {
return (
<div className="App">
<Provider store={store}>// ..</Provider>
</div>
);
};
// ...
现在的问题是,我们如何创建这家商店?
答案:createStore()。
createStore ()函数接受一个Reducer函数并返回一个包含应用程序完整状态树的 Redux 存储对象。
Reducer是一个返回应用程序当前状态的函数。
// ..
import { Provider } from "react-redux";
import { createStore } from "redux";
function reducer() {
// ..
return {
count: 0
};
}
const store = createStore(reducer);
const App = () => {
return (
<div className="App">
<Provider store={store}>// ..</Provider>
</div>
);
};
// ...
目前,Reducer仅返回应用程序的初始状态。
index.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";
import "./styles.css";
import Parent from "./Parent";
const initialState = {
count: 0
};
function reducer(state = initialState) {
// ..
return {
count: state.count
};
}
const store = createStore(reducer);
const App = () => {
return (
<div className="App">
<Provider store={store}>
<Parent />
</Provider>
</div>
);
};
// ...
在本指南的后面部分中,我们将看到如何指示 Reducer 返回当前状态或改变后的状态。
构建我们的组件
在这个例子中,我们将有 3 个组件:<Parent />、<Child />和<GrandChild /> 。我们将在<Parent />组件中创建一个按钮,并在按钮单击时增加计数器值,该值将传递给<GrandChild />组件。
那么,让我们从<GrandChild />组件开始。
GrandChild.js
import React from "react";
import { connect } from "react-redux";
const GrandChild = props => (
<div className="grandchild-component">
<div>This is the grandchild component</div>
<div class="emp">Count: {props.count}</div>
</div>
);
const mapStateToProps = state => ({
count: state.count
});
export default connect(mapStateToProps)(GrandChild);
我们上面看到的这个奇怪的连接函数是什么?
connect()是一个高阶函数,用于将组件与 Redux 存储连接起来。存储是整个应用程序的全局状态所在。
当我们调用connect ()函数时,它会返回一个函数,并且我们将 React 组件传递给返回的函数,然后该组件返回一个连接的组件;这就是为什么connect函数调用看起来如此奇怪的原因。
然后我们导出带有所有必要道具的连接的<GrandChild />组件。
mapStateToProps ()函数是一个自定义函数,而不是 Redux 特有的函数。正如函数名称所示,其目的是仅将全局状态中的必要数据作为 props 返回给组件。
Child.js
< Child />将成为一个简单的组件,它仅仅包装<GrandChild />组件。
const Child = () => (
<div className="child-component">
<div>This is the child component</div>
<Grandchild />
</div>
);
父类.js
我们将把<Parent />组件与 Redux 连接起来,不是为了访问商店,而是为了分派 动作。
操作只是一个包含type属性的对象,该属性的值必须是字符串,表示操作的目的。它可以包含其他可选属性,例如与该操作相关的有效负载或数据。
我们将在按钮点击时发送INCREMENT操作。
// ...
import { connect } from "react-redux";
class Parent extends Component {
increment = () => {
// dispatch the action
};
render() {
return (
<div className="parent-component">
<div>This is the parent component</div>
<button onClick={this.increment}>Click Me!!</button>
<Child />
</div>
);
}
}
export default connect(null)(Parent);
由于该组件不需要状态,我们将null传递给connect()函数。
除了状态之外,连接的组件还可以访问dispatch()函数,该函数将动作对象作为参数。
increment = () => {
this.props.dispatch({ type: "INCREMENT" });
};
完成 Reducer
我们可以将action作为第二个参数传递给Reducer,并且根据 action 类型,我们可以从函数返回状态。
const initialState = {
count: 0
};
function reducer(state = initialState, action) {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
default:
return {
count: state.count
};
}
}
完整源代码
index.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";
import "./styles.css";
import Parent from "./Parent";
const initialState = {
count: 0
};
function reducer(state = initialState, action) {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
default:
return {
count: state.count
};
}
}
const store = createStore(reducer);
const App = () => {
return (
<div className="App">
<Provider store={store}>
<Parent />
</Provider>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
父类.js
import React, { Component } from "react";
import { connect } from "react-redux";
import Child from "./Child";
class Parent extends Component {
increment = () => {
this.props.dispatch({ type: "INCREMENT" });
};
render() {
return (
<div className="parent-component">
<div>This is the parent component</div>
<button onClick={this.increment}>Click Me!!</button>
<Child />
</div>
);
}
}
export <span class
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~