【问题标题】:Pass state to recursively nested component in React/Redux将状态传递给 React/Redux 中的递归嵌套组件
【发布时间】:2016-08-31 08:16:02
【问题描述】:

我有一个组件,它的子组件与组件本身的类型相同。我也可以渲染孩子们,但孩子们似乎无法访问他们的状态片段。我正在将 React 与 Redux 一起使用

export class Material extends React.Component {

  constructor(props) {
    super(props)
    this.renderChild = this.renderChild.bind(this)
    this.getNestedItems = this.getNestedItems.bind(this)
  }

  static propTypes = {
    parentId: PropTypes.number,
    id: PropTypes.number.isRequired,
    name: PropTypes.string.isRequired,
    subtext: PropTypes.string.isRequired,
    childIds: PropTypes.arrayOf(PropTypes.number.isRequired),
    fileType: PropTypes.string.isRequired
  }

  // This is where I am having trouble.
  // Shouldn't the props be accessible from state itself?

  renderChild = (id, childId) => (
      <Material key={childId}
        id={childId}
        parentId={id}
        name={name}
        subtext={subtext}
        fileType={fileType}
        />
    )

  getNestedItems = (id, childIds) => {
    console.log("id: " + id)
    console.log("childIds: " + childIds)
    var childItems = []
    for(var i=0; i < childIds.length; i++){
        var child = this.renderChild(id, childIds[i])
        childItems.push(child)
    }
    return childItems
  }

  render(){

    let childItems = []
    if(this.props.childIds){
      childItems = this.getNestedItems(this.props.id, this.props.childIds)
    }

    return(
      <ListItem
        leftAvatar={<Avatar icon={fileType.length === 0 ? <FileFolder /> : <ActionAssignment />} />}
        rightIcon={fileType.length === 0 ? <AddCircle /> : <ActionInfo />}
        primaryText={name}
        secondaryText={subtext}
        initiallyOpen={fileType.length === 0} // fileType is empty if it is a folder
        primaryTogglesNestedList={fileType.length === 0}
        nestedItems={childItems} // one has to pass an array of elements
      />
    )
  }
}

const mapStateToProps = (state, ownProps) => {
  return {
    id: ownProps.id,
    name: state.Material[ownProps.id].name,
    subtext: state.Material[ownProps.id].subtext,
    childIds: state.Material[ownProps.id].childIds,
    fileType: state.Material[ownProps.id].fileType,
  }
}

export default connect(
  mapStateToProps
)(Material)

另外,我正在使用 ListItem from Material-ui(这些最终在 List 组件中呈现)并且我的代码受到官方 redux repo 中 tree-view example 的严重影响。我的状态是这样的:

const initialState = {
  0: {
      id: 0,
      name: 'Root',
      subtext: 'Some subtext',
      fileType: '',
      childIds: [1]
    },
  1: {
      id: 1,
      name: 'Child',
      subtext: 'Child subtext',
      fileType: 'png',
      childIds: []
    }

}

显示的状态与树视图示例中的结构相同

【问题讨论】:

    标签: reactjs redux material-ui react-redux


    【解决方案1】:

    好吧,如果我理解正确的话,你希望这些 Material 组件从 redux 存储中获取它的数据。
    如果这就是您想要实现的目标,您需要为每个 Material 提供对 redux 存储的访问权限。基本上你需要用connect HOC 包裹所有这些。
    示例:

    const MaterialContainer = connect(mapStateToProps)(Material);
    

    renderChild 函数中,您将使用这个MaterialContainer

    renderChild = (id) => (
      <MaterialContainer key={childId} id={childId} />
    )
    

    你可以看到它在这里工作 https://jsbin.com/taquke/edit?js,output

    【讨论】:

    • 是的,它有效!你的回答让我意识到错误是什么。我还将组件拆分为展示组件和容器组件,但我将展示组件呈现为嵌套子组件而不是容器。
    • 这为我解决了完全相同的问题,谢谢。我很好奇为什么这不是由我们已经附加到组件的mapStateToProps 处理的。不过,当我输入上一句时,我意识到这正是因为我们只使用mapStateToProps 进行导出。递归嵌套的子级在导出之前调用组件函数,因此需要单独应用mapStateToProps
    猜你喜欢
    • 1970-01-01
    • 2017-01-26
    • 2016-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 2019-01-20
    • 2022-01-18
    • 2019-02-17
    相关资源
    最近更新 更多