Redux 把公共数据都放在 store 这个公用的存储空间中,组件尽量少放数据。
一、.当一个组件想要去改变数据传递给其他组件的时候怎么办?
这个组件只需要去改变 store 的数据,接着,其他用了这个数据的组件会自动感应到store的变化,并会去 store 里重新取数据。
二、Redux = Reducer + Flux
三、Redux的流程
![](https://img.haomeiwen.com/i12688258/ccbc02e9c36ca0f8.jpg)
四、应用,使用React 结合 Redux 重新 编写 TodoList
安装 Redux
yarn add redux
redux
1.在 src 下新建 store 文件夹,store 文件夹 下新建 index.js 和 reducer.js 文件
![](https://img.haomeiwen.com/i12688258/4aa00cbdadb8b4be.png)
index.js
import { createStore } from 'redux'
import reducer from './reducer'
//// 创建 store 的时候把 reducer 的 公用的数据传给 store
const store = createStore(reducer);
export default store
reducer.js 负责管理整个应用的数据
// 存放公用的数据
const defaultDate = {
inputValue: 'hello',
list: ['1', '2', '3', '4', '5']
}
// reducer 返回的必须是一个函数,这个函数接收两个参数(state 和 action)
export default (state = defaultDate, action) => {
return state
// 返回 state
}
2.然后在 TodoList.js 中可以访问到 reducer.js 中公用的数据(获取Store)
先在 TodoList.js头部 引入
import store from './store/index.js'
这样就能访问到
constructor(props) {
super(props)
// 这时候组件的数据来源于 store
this.state = store.getState()
console.log(this.state); //{inputValue: "", list: Array(0)}
console.log(store.getState()); //{inputValue: "", list: Array(0)}
}
在 TodoList.js 组件中使用store的公用数据
![](https://img.haomeiwen.com/i12688258/18e70014bb6edfbc.png)
render() {
return (
<div style={{ marginTop: '10px', marginLeft: '10px' }}>
<div>
<Input value={this.state.inputValue} placeholder="todo info" style={{ width: '300px', marginRight: '10px' }} />
<Button type="primary">提交</Button>
<List style={{ marginTop: '10px', width: '300px' }}
bordered
dataSource={this.state.list}
renderItem={item => (
<List.Item>
{item}
</List.Item>
)}
/>
</div>
</div>
)
}
3.Action 和 Reducer 的编写(改变 Store)
我们希望当 input 框输入的内容改变时,State 的公用数据 inputValue 也变化
![](https://img.haomeiwen.com/i12688258/de58b24d25e6ed36.png)
在 TodoList.js 中
<Input value={this.state.inputValue} placeholder="todo info" style={{ width: '300px', marginRight: '10px' }} onChange={this.handleInputChange} />
handleInputChange(e) {
// 1.创建action方法
const action = {
type: 'change_input_value',
value: e.target.value
}
//2.调用store 的 dispatch把 action 派发给store
//Store 接收到 action 会自动帮我们把 之前的数据(previousState)和 action 传递给 Reducer
store.dispatch(action)
console.log(e.target.value);
}
reducer.js 中
打印出 过去的数据和action
![](https://img.haomeiwen.com/i12688258/628865bc7a00b8b7.png)
// 存放公用的数据
const defaultDate = {
inputValue: 'hello',
list: ['1', '2', '3', '4', '5']
}
// reducer 返回的必须是一个函数,这个函数接收两个参数(state 和 action)
// state = defaultDate 表示 Store 上一次 存储的数据,action 表示用户传过来的话
// reducer 可以接收state,但是不能修改state
export default (state = defaultDate, action) => {
console.log(state, action);
if (action.type === 'change_input_value') {
const newState = JSON.parse(JSON.stringify(state))
// 把inputValue改成最新的value
newState.inputValue = action.value
return newState
}
return state
// 返回 state
}
接着 在 TodoList.js 中的 constructor 订阅store
constructor(props) {
super(props)
// 这时候组件的数据来源于 store
this.state = store.getState()
console.log(this.state); //{inputValue: "", list: Array(0)}
console.log(store.getState()); //{inputValue: "", list: Array(0)}
this.handleInputChange = this.handleInputChange.bind(this)
// 组件去订阅store,只要store发生改变,this.handleStoreChange就会执行一次
this.handleStoreChange = this.handleStoreChange.bind(this)
store.subscribe(this.handleStoreChange)
}
并且定义 this.handleStoreChange 这个方法
handleStoreChange() {
this.setState(store.getState())
}
一篇写不下,下篇 Redux(2) 直接给demo 完整 代码
需要完整代码,也可以加我微信: hello_helloxi
网友评论