react17.x中react-redux的基本使用

使用之前安装react-redux:npm install react-redux

一个项目中用到store中数据的组件有很多,所以应该把他放在App.js
在App.js中引入react-redux。并将子组件使用Provider组件包裹起来

子组件被Provider组件包裹起来后,每个子组件都能通过一些方法获取到store中的数据,将store传递给每个被包裹的子组件

app.js

import TodoList from './views/TodoList'
import {
      Provider } from 'react-redux'
import store from './store'

function App() {
     
  return (
    <div className="App">
      <Provider store={
     store}>
        <TodoList />
      </Provider>
    </div>
  );
}

export default App;

store.js

import {
      createStore } from 'redux'
import reducer from './reducer'

const store = createStore(
    reducer
)


export default store

reducer.js

const defaultState = {
     
    inputVal: 'hello word',
    list: []
}

// reducer中需要返回一个函数,接收旧的 state 和 action,返回新的 state
export default (state = defaultState, action) => {
     
    return state
}

那么如何在todolist中使用呢

首先在头部引入react-redux的connect方法
connect方法是将该组件和store连接,通过mapStateToProps来连接

import {
      connect } from 'react-redux'
class TodoList extends Component {
     
    constructor(props){
     
        super(props)
    }
    inputValChange = (e) => {
     
        // console.log(e.target.value)
        let {
      changeInputVal } = this.props
        changeInputVal(e.target.value)
    }
    onSubmit = () => {
     

    }
    render() {
     
        let {
      inputVal } = this.props
        return (
            <div>
                <input type="text" onChange={
     (e) => this.inputValChange(e)} defaultValue={
     inputVal} />
                <button onClick={
     () => this.onSubmit()}>提交</button>
                {
     /* <ul>
                    {
     
                        list.map((item,index) => {
     
                            return <li key={
     index}>{
     item}</li>
                        })
                    }
                </ul> */}
            </div>
        )
    }
}

// 将store中的state数据映射给组件,变成组件的props
const mapStateToProps = (state,ownProps)=> {
     
    return {
     
        inputVal: state.inputVal
    }
}

//将dispatch方法映射到组件的props
const mapDispatchToProps = dispatch => {
     
    return {
     
        changeInputVal: (inputVal) => {
     
            dispatch({
     
                type: 'changeInputVal',
                payload: inputVal
            })
            // console.log(inputVal)
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoList)

mapDispatchToProps 和mapStateToProps直接将store中的state数据、dispatch方法映射到组件的props中;
当我们使用了mapDispatchToProps 和mapStateToProps 后,就可以直接通过this.props.xxxx来获取
如果我们不希望更新数据的话,将前两个值改为null即可

mapStateToProps 第二个参数只要存储状态发生变化或包装器组件收到新的props(基于浅层相等性比较),就会调用该函数

这时候reducer.js代码就需要接收新的state数据并返回了

在上面我的input组件绑定的是defaultValue,而并不是value,使用value的话会有一个报错,意思是:Input 组件从一个非受控组件变成了一个受控组件
造成这个问题的原因是:初始化时,Input 组件的value值为undefined或者是空。
react17.x中react-redux的基本使用_第1张图片
有两种方法解决,一种是value改为defaultValue
第二种是在reducer.js中,将state进行一次深拷贝,就是下方注释的代码


const defaultState = {
     
    inputVal: 'hello word',
    list: []
}

export default (state = defaultState, action) => {
     
    console.log(action)
    const {
      type, payload } = action
    if (!payload) return state
    if (type === 'changeInputVal') {
     
        return payload
        // const newState = JSON.parse(JSON.stringify(state))
        // newState.inputVal = payload
        // return newState
    }
    // return state
}

你可能感兴趣的:(react)