我试图理解react-redux的连接方法,以及它作为参数的函数。特别是mapStateToProps()。

我理解它的方式,mapStateToProps的返回值将是一个从状态派生的对象(因为它存在于存储中),它的键将作为道具传递给您的目标组件(组件连接被应用到)。

这意味着目标组件使用的状态可能与存储在存储库中的状态具有完全不同的结构。

问:这样可以吗? 问:这是预期的吗? 问:这是反模式吗?


当前回答

This react & redux example is based off Mohamed Mellouki's example. But validates using prettify and linting rules. Note that we define our props and dispatch methods using PropTypes so that our compiler doesn't scream at us. This example also included some lines of code that had been missing in Mohamed's example. To use connect you will need to import it from react-redux. This example also binds the method filterItems this will prevent scope problems in the component. This source code has been auto formatted using JavaScript Prettify.

import React, { Component } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

class ItemsContainer extends Component {
  constructor(props) {
    super(props);
    const { items, filters } = props;
    this.state = {
      items,
      filteredItems: filterItems(items, filters),
    };
    this.filterItems = this.filterItems.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const { itmes } = this.state;
    const { filters } = nextProps;
    this.setState({ filteredItems: filterItems(items, filters) });
  }

  filterItems = (items, filters) => {
    /* return filtered list */
  };

  render() {
    return <View>/*display the filtered items */</View>;
  }
}

/*
define dispatch methods in propTypes so that they are validated.
*/
ItemsContainer.propTypes = {
  items: PropTypes.array.isRequired,
  filters: PropTypes.array.isRequired,
  onMyAction: PropTypes.func.isRequired,
};

/*
map state to props
*/
const mapStateToProps = state => ({
  items: state.App.Items.List,
  filters: state.App.Items.Filters,
});

/*
connect dispatch to props so that you can call the methods from the active props scope.
The defined method `onMyAction` can be called in the scope of the componets props.
*/
const mapDispatchToProps = dispatch => ({
  onMyAction: value => {
    dispatch(() => console.log(`${value}`));
  },
});

/* clean way of setting up the connect. */
export default connect(mapStateToProps, mapDispatchToProps)(ItemsContainer);

这个示例代码是一个很好的模板,可以作为组件的起点。

其他回答

问:这样可以吗? 是的

问:这是预期的吗? 是的,这是预期的(如果您正在使用react-redux)。

问:这是反模式吗? 答:不,这不是反模式。

这被称为“连接”组件或“使其智能”。这是设计出来的。

它允许您在额外的时间内将组件与状态解耦,从而增加代码的模块化。它还允许您将组件状态简化为应用程序状态的子集,这实际上有助于您遵守Redux模式。

可以这样考虑:存储应该包含应用程序的整个状态。 对于大型应用程序,这可能包含数十个嵌套在多层深处的属性。 你不希望每次通话都带着这些东西(很贵)。

如果没有mapStateToProps或类似的东西,您可能会倾向于以另一种方式分割状态以提高性能/简化。

下面是描述mapStateToProps行为的大纲/样板:

(这是Redux容器功能的极大简化实现。)

class MyComponentContainer extends Component {
  mapStateToProps(state) {
    // this function is specific to this particular container
    return state.foo.bar;
  }

  render() {
    // This is how you get the current state from Redux,
    // and would be identical, no mater what mapStateToProps does
    const { state } = this.context.store.getState();

    const props = this.mapStateToProps(state);

    return <MyComponent {...this.props} {...props} />;
  }
}

和明年

function buildReduxContainer(ChildComponentClass, mapStateToProps) {
  return class Container extends Component {
    render() {
      const { state } = this.context.store.getState();

      const props = mapStateToProps(state);

      return <ChildComponentClass {...this.props} {...props} />;
    }
  }
}

It's a simple concept. Redux creates a ubiquitous state object (a store) from the actions in the reducers. Like a React component, this state doesn't have to be explicitly coded anywhere, but it helps developers to see a default state object in the reducer file to visualise what is happening. You import the reducer in the component to access the file. Then mapStateToProps selects only the key/value pairs in the store that its component needs. Think of it like Redux creating a global version of a React component's

this.state = ({ 
cats = [], 
dogs = []
})

不可能通过使用mapStateToProps()来改变状态的结构。您所做的只是选择组件需要的存储键/值对,并将值(从存储中的键/值列表中)传递给组件中的道具(本地键)。在列表中,每次只执行一个值。在此过程中不会发生结构更改。

附注:商店是本地的。reducer通常也将状态传递给数据库,与Action creator一起混合,但首先要理解这个简单的概念。

P.P.S.将每个减速器分离到单独的文件中,并且只导入组件需要的减速器,这是一个很好的做法。

import React from 'react';
import {connect} from 'react-redux';
import Userlist from './Userlist';

class Userdetails extends React.Component{

render(){
    return(
        <div>
            <p>Name : <span>{this.props.user.name}</span></p>
            <p>ID : <span>{this.props.user.id}</span></p>
            <p>Working : <span>{this.props.user.Working}</span></p>
            <p>Age : <span>{this.props.user.age}</span></p>
        </div>
    );
 }

}

 function mapStateToProps(state){  
  return {
    user:state.activeUser  
}

}

  export default connect(mapStateToProps, null)(Userdetails);

This react & redux example is based off Mohamed Mellouki's example. But validates using prettify and linting rules. Note that we define our props and dispatch methods using PropTypes so that our compiler doesn't scream at us. This example also included some lines of code that had been missing in Mohamed's example. To use connect you will need to import it from react-redux. This example also binds the method filterItems this will prevent scope problems in the component. This source code has been auto formatted using JavaScript Prettify.

import React, { Component } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

class ItemsContainer extends Component {
  constructor(props) {
    super(props);
    const { items, filters } = props;
    this.state = {
      items,
      filteredItems: filterItems(items, filters),
    };
    this.filterItems = this.filterItems.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const { itmes } = this.state;
    const { filters } = nextProps;
    this.setState({ filteredItems: filterItems(items, filters) });
  }

  filterItems = (items, filters) => {
    /* return filtered list */
  };

  render() {
    return <View>/*display the filtered items */</View>;
  }
}

/*
define dispatch methods in propTypes so that they are validated.
*/
ItemsContainer.propTypes = {
  items: PropTypes.array.isRequired,
  filters: PropTypes.array.isRequired,
  onMyAction: PropTypes.func.isRequired,
};

/*
map state to props
*/
const mapStateToProps = state => ({
  items: state.App.Items.List,
  filters: state.App.Items.Filters,
});

/*
connect dispatch to props so that you can call the methods from the active props scope.
The defined method `onMyAction` can be called in the scope of the componets props.
*/
const mapDispatchToProps = dispatch => ({
  onMyAction: value => {
    dispatch(() => console.log(`${value}`));
  },
});

/* clean way of setting up the connect. */
export default connect(mapStateToProps, mapDispatchToProps)(ItemsContainer);

这个示例代码是一个很好的模板,可以作为组件的起点。