美文网首页
(十八)Redux(1)

(十八)Redux(1)

作者: 云凡的云凡 | 来源:发表于2020-10-28 15:38 被阅读0次

Redux 把公共数据都放在 store 这个公用的存储空间中,组件尽量少放数据。

一、.当一个组件想要去改变数据传递给其他组件的时候怎么办?

这个组件只需要去改变 store 的数据,接着,其他用了这个数据的组件会自动感应到store的变化,并会去 store 里重新取数据。

二、Redux = Reducer + Flux
三、Redux的流程
redux.jpg
四、应用,使用React 结合 Redux 重新 编写 TodoList

安装 Redux
yarn add redux
redux

1.在 src 下新建 store 文件夹,store 文件夹 下新建 index.js 和 reducer.js 文件


image.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的公用数据


image.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 也变化


image.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


image.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

相关文章

网友评论

      本文标题:(十八)Redux(1)

      本文链接:https://www.haomeiwen.com/subject/uuqlmktx.html