具有相同动作的可重复使用的React组件&减速机

时间:2017-03-27 21:46:47

标签: reactjs react-redux reducers

我想重用一个反应组件并分享共同的行动&减速。我的应用仪表板有3个列表,其中每个列表都使用不同的查询参数获取。

所有3个List组件都有相同的道具,因为一旦我从reducer收到道具,它们中的所有3个都会被重新渲染。

是否有基于查询参数显示列表的动态方式?我在想的是根据查询参数在动作文件中调用不同的reducer。还有更好的方法吗?

Dashboard.js

 const Dashboard = () => {
      return(
        <div>
          <List query={QUERY1} />
          <List query={QUERY2} />
          <List query={QUERY3} />
        </div>
      )
    }

List.js

class List extends Component {

  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
  }

  componentWillMount() {
    const { query } = this.props;
    this.props.onLoad(query);
  }

  componentWillReceiveProps() {
    const { items } = this.props;
    this.setState({ items });
  }

  render() {

    return (
      <div>
          {
            this.state.items.map((item, index) =>
              <Item data={item} key={index}/>
            )
          }
      </div>
    )
  }
}


function mapStateToProps(state) {
  const { items } = state.item;
  return {
    items
  }
}

function mapDispatchToProps(dispatch) {
  return {
    onLoad: bindActionCreators(actions.load, dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(List);

action.js

export function load(query) {
  return function (dispatch) {
    fetch(`//api.example.com/list?type=${query}&limit=10`)
      .then((response) => response.json())
      .then((data) => {
        dispatch(setItems(data));
      });
  };
}

reducer.js

export default function(state = [], action) {
  switch (action.type) {
    case actionTypes.ITEMS_SET:
      return setItems(state, action);
  }
  return state;
}

function setItems(state, action) {
  const { items } = action;
  return { ...state, items };
}

1 个答案:

答案 0 :(得分:1)

注意我是redux-subpace的贡献者

redux-subspace来解决这个问题,即在页面上显示相同的组件,而不会越过商店值。

它有一个名为namespacing的功能,可以让您将加载操作和组件相互隔离。

const Dashboard = () => {
  return(
    <div>
      <SubspaceProvider mapState={state => state.list1}, namespace='list1'>
        <List query={QUERY1} />
      </SubspaceProvider>
      <SubspaceProvider mapState={state => state.list2}, namespace='list'>
        <List query={QUERY2} />
      </SubspaceProvider>
      <SubspaceProvider mapState={state => state.list3}, namespace='list3'>
        <List query={QUERY3} />
      </SubspaceProvider>
    </div>
  )
}

您还需要为缩减器命名空间,您可以看到如何执行此操作here