【问题标题】:React/Redux/ImmutableJS get() returns undefinedReact/Redux/ImmutableJS get() 返回未定义
【发布时间】:2017-11-07 01:03:19
【问题描述】:

我正在尝试通过将有效负载与 Map() 的初始状态合并来更新我的 redux 存储。我可以在 mapStateToProps 中使用点表示法访问状态属性,但是在尝试调用 state.get('prop') 时,该值未定义。

actions.js

export function loadPackages() {
  return function(dispatch) {
    return PackageApi.getAllPackages().then(packages => {
      dispatch(loadPackagesSuccess(packages));
    }).catch(error => {
      throw(error);
    });
  };
}

export function loadPackagesSuccess(packages) {
  return {
    type: 'LOAD_PACKAGES_SUCCESS',
    packages
  }
}

reducer.js

const reducer = (state = Map(), action) => {
  switch (action.type) {
    case 'LOAD_PACKAGES_SUCCESS':
      return update(state, {$merge: action.packages});
    default:
      return state;
  }
}

export default reducer;

Packages.jsx

const mapStateToProps = (state) => {
  console.log(state.results); // (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
  return {
    state,
    packages: state.get('results') // undefined
  };
}

编辑

reducer.js

const initialState = Map({
  packages: {
    totalCount: null,
    results: List(),
    dir: null,
    totalPages: null,
    limit: null,
    sort: null,
    page: null
  }
});

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'LOAD_PACKAGES_SUCCESS':
      return state.set('packages', fromJS(action.packages));
    default:
      return state;
  }
}

Packages.jsx

export class Packages extends React.Component {
  componentDidMount() {
    this.props.dispatch(loadPackages(this.props.state));
  }
  render() {
    return (
      <div className="col-lg-12">
        {this.props.results ?
        <PackageList allPackages={this.props.results} /> :
        <h3>No Packages Available</h3>}
      </div>
    );
  }
};

const mapStateToProps = (state) => {
  console.log(state.getIn(['packages','results'])); 
  /* Doesn't print the actual value of results but shows the 
     immutable structure: List {size: 10, _origin: 0, _capacity: 10, 
     _level: 5, _root: null, …} */
  return {
    packages: state.get('packages'),
    results: state.getIn(['packages','results'])
  };
}

PackageList.jsx

const PackageList = ({allPackages}) => {
  const packageItems = allPackages.map(pkg =>
    <li key={pkg.get('id')}>{pkg.get('packageName')}</li>
  );
  return (
    <ul className="packages">
      {packageItems}
    </ul>
  );
};

【问题讨论】:

    标签: react-redux immutable.js


    【解决方案1】:

    如果 state 中的结构错误,则表示 reducer 有问题。

    替换这个:return update(state, {$merge: action.packages});

    有了这个:return state.set('packages', Immutable.fromJs(action.packages));

    现在您使用来自https://reactjs.org/docs/update.html 的 vanilla js 不可变数据变异助手,它返回新的基本 JS 对象/数组等,并且与 Immutable.Js 库无关,您尝试在裸 JS 对象上使用 Immutable.js 方法。

    【讨论】:

    • 我明白了。我更新了您建议的更改,并且可以使用 get() 和 getIn() 从状态中获取值。当我迭代结果时,我能够呈现有效负载属性的唯一方法是调用 item.get('prop')。这是迭代不可变结构的正确方法吗?此外,将 state.getIn(['packages','results']) 记录到控制台不会打印属性值,它只是显示值的不可变描述。
    • @neridaj 如果“results”是另一个不可变结构,那么它将打印它。您可以使用.toJS() 转回 js。要从不可变的 js 结构中获取价值,您必须使用 .get.getIn,是的。
    猜你喜欢
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 2018-10-14
    • 2021-04-28
    • 2018-12-31
    • 2019-04-28
    • 2020-11-23
    相关资源
    最近更新 更多