React-Redux的mapStateToProps以意外的方式工作

时间:2019-07-26 06:33:22

标签: reactjs redux react-redux

我有一个组件,显示从Redux存储中获取的名称列表。该组件如下所示:

class Details extends React.Component {

  constructor (props) {
    super(props);
  }

  render () {
    const listName = [...this.props.listName];
    return (
      <div className="container detailsBox">
        <p>Details Grid:</p>
        {listName ? (
          listName.map((el, index) => {
            return (
              <li key={index}>
                {el}
              </li>
            )
          })
        ): null}
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    listName: state.listName
  }
}

export default connect(mapStateToProps)(Details);

请注意,这里我仅映射商店中的listName。但是,即使登录控制台显示<li>填充了数据,该代码也不会显示listName及其元素listName

但是当从商店中获取name时,数据也按预期显示,并在mapStateToProps中进行了修改:

const mapStateToProps = (state) => {
  return {
    listName: state.listName,
    name: state.name
  }
}

我很困惑,也想知道为什么代码会以这种意外的方式运行?我在这里想念什么?

reducer代码如下:

import { UPDATE_NAME, ADD_NAME } from '../actions/addName.action';

const initialState = {
  name: '',
  listName: new Set()
}

function rootReducer (state = initialState, action) {
  switch (action.type) {
    case ADD_NAME:
      return {
        name: '',
        listName: state.listName.add(action.payload)
      }
    case UPDATE_NAME:
      return {
        ...state,
        name: action.payload
      }
    default:
      return state;
  }
}

export default rootReducer;

以及类似的动作:

export const ADD_NAME = 'ADD_NAME';
export const UPDATE_NAME = 'UPDATE_NAME';

export function addName (data) {
  return {
    type: ADD_NAME,
    payload: data
  }
}

export function updateName (name) {
  return {
    type: UPDATE_NAME,
    payload: name
  }
}

2 个答案:

答案 0 :(得分:2)

之所以发生这种情况,是因为您改变了状态。当您对listNames进行突变时,它仍然指向内存中的同一对象,并且当listNames的内容发生变化时,React认为没有任何变化。您应该返回一个新对象。

case ADD_NAME:
  return {
    name: '',
    listName: new Set([...state.listName, action.payload]),
  }

但是不建议在减速器中使用Set。相反,您可以将listNames存储为数组,并使用lodash union函数仅具有唯一值。

import { union } from 'lodash';

const initialState = {
  name: '',
  listName: []
}

// some code

case ADD_NAME:
  return {
    name: '',
    listName: union(state.listNames, action.payload)
  }

答案 1 :(得分:0)

您可以改为使用一个对象来保存listName,然后将状态结构重新创建为一个新对象,然后返回。

const initialState = {
  name: '',
  listName: {}
}

case ADD_NAME:
  return {
    name: '',
    listName: {...state.listName, action.payload}
  }