javascript - react redux 将数据分配给组件

标签 javascript reactjs redux

我搜索了一圈,所有的问题都是关于How to pass props to {this.props.children}

但我的情况不同, 我用初始数据填充 App -- nodes,并将 nodes 映射到 TreeNode 列表,我想要每个 TreeNode 都具有传入的 node 属性。

伪代码:

应用渲染:

{nodes.map(node => 
<TreeNode key={node.name} info={node} /> 
)} 

树节点渲染:

const { actions, nodes, info } = this.props 
return ( 
<a>{info.name}</a> 
); 

似乎节点没有作为信息传入,日志显示信息未定义。

warning.js?8a56:45 Warning: Failed propType: Required prop `info` was not specified in `TreeNode`. Check the render method of `Connect(TreeNode)`. 

TreeNode.js?10ab:57 Uncaught TypeError: Cannot read property 'name' of undefined 

下面只是一个更完整的代码与这个问题相关(我认为存储和操作没有太大关系):

容器/App.js:

import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import Footer from '../components/Footer';
import TreeNode from '../containers/TreeNode';
import Home from '../containers/Home';
import * as NodeActions from '../actions/NodeActions'

export default class App extends Component {

  componentWillMount() {
    // this will update the nodes on state
    this.props.actions.getNodes();
  }

  render() {
    const { nodes } = this.props
    console.log(nodes)
    return (
      <div className="main-app-container">
        <Home />
        <div className="main-app-nav">Simple Redux Boilerplate</div>
        <div>
          {nodes.map(node =>
            <TreeNode key={node.name} info={node} />
          )}
        </div>

        <Footer />
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    nodes: state.opener.nodes
  };
}


function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(NodeActions, dispatch)
  };
}

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

容器/TreeNode.js

import React, { Component, PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import classNames from 'classnames/bind'
import * as NodeActions from '../actions/NodeActions'

class TreeNode extends Component {


  handleClick() {
    this.setState({ open: !this.state.open })
    if (this.state.open){
      this.actions.getNodes()
    }
  }

  render() {
    const { actions, nodes, info } = this.props

    if (nodes) {
      const children =<div>{nodes.map(node => <TreeNode info={node} />)}</div>
    } else {
      const children = <div>no open</div>
    }

    return (
      <div className={classNames('tree-node', { 'open':this.props.open})} onClick={ () => {this.handleClick()} }>
        <a>{info.name}</a>
        {children}
      </div>
    );
  }
}

TreeNode.propTypes = {
  info:PropTypes.object.isRequired,
  actions: PropTypes.object.isRequired
}


function mapStateToProps(state) {
  return {
    open: state.open,
    info: state.info,
    nodes: state.nodes
  };
}


function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(NodeActions, dispatch)
  };
}


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

reducers/TreeNodeReducer.js

import { OPEN_NODE, CLOSE_NODE, GET_NODES } from '../constants/NodeActionTypes';

const initialState = {
  open: false,
  nodes: [],
  info: {}
}


const testNodes = [
  {name:'t1',type:'t1'},
  {name:'t2',type:'t2'},
  {name:'t3',type:'t3'},
]


function getFileList() {
  return {
    nodes: testNodes
  }
}


export default function opener(state = initialState, action) {
  switch (action.type) {
  case OPEN_NODE:
    var {nodes} = getFileList()  
    return {
      ...state,
      open:true,
      nodes:nodes
    };
  case CLOSE_NODE:
    return {
      ...state,
      open:false
    };
  case GET_NODES:
    var {nodes} = getFileList()
    return {
      ...state,
      nodes:nodes
    };
  default:
    return state;
  }
}

完整代码可以看我的github https://github.com/eromoe/simple-redux-boilerplate

这个错误让我很困惑。我看到的 sulotion 是 parent 已经有一些 child ,然后使用 react.Children 为他们提供 Prop ,他们不使用 redux。

最佳答案

nodes 值上循环时,调用 TreeNode 并赋予属性 info:这很好!

但是当你的组件被渲染时,这个函数被调用:

function mapStateToProps(state) {
  return {
    open: state.open,
    info: state.info,
    nodes: state.nodes
  };
}

如您所见,info 属性将被 state.info 中的值覆盖。 state.info 值是 undefined 我认为。因此 React 会警告您 TreeNode 需要此值。此警告来自您的组件配置:

TreeNode.propTypes = {
  info:PropTypes.object.isRequired
}

为什么 state.info 是未定义的?我认为您没有按应有的方式调用它。您应该调用 state['reducerNameSavedWhenCreatingReduxStore].info 进行检索{}`。

您不应该通过 propsconnect() 来填充 ThreeNode

关于javascript - react redux 将数据分配给组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37921749/

相关文章:

javascript - 根元素ID与reactRootID不同

javascript - redux 和状态机(例如 xstate)之间的实际区别是什么?

javascript - await 是 async 函数内部的保留字错误

javascript - 在javascript中从数组中读取数据

javascript - Node.js 源代码需要什么编码?

javascript 拆分未定义的数组

reactjs - 将文本添加到 Switch formcontrol 并使用 material ui 在 toggle 中更改它

javascript - 在 React 中保存本地状态

javascript - 使用 websocket 在浏览器和 java SE 项目之间传递数据

react-native - React-Navigation with redux - StackNavigator 中嵌套在 TabNavigator 中的后退按钮触发两个导航器中的后退 Action