避免无法阅读财产' map'反应还原中未定义的

时间:2016-06-21 02:22:53

标签: javascript reactjs redux

我看到了一些像Cannot read property 'map' of undefined这样的答案,但它是为了反应,而不是在react-redux中工作。

主要代码:

容器/ 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'

export default class TreeNode extends Component {

  // getInitialState() {
  //     return {nodes:[]};
  // }

  // warning.js?8a56:45 Warning: getInitialState was defined on TreeNode, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?

  constructor(props, context) {
    super(props, context)
    this.props = {
      open: false,
      nodes: [],
      info:{}
    }
  }

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

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

    console.log(this.props)
    console.log(nodes===undefined)

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


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

nodes.map会抛出错误cannot read property 'map' of undefined,我知道节点可能未定义。

我试过了

  1. 添加getInitialState

    getInitialState() {
      return {nodes:[]};
    }
    

    得到:warning.js?8a56:45 Warning: getInitialState was defined on TreeNode, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?

  2. 这是说getInitialState不能在组件中使用。

    1. 更改渲染以使用if else:

       render() {
          const { actions, nodes, info } = this.props
      
          console.log(this.props)
          console.log(nodes===undefined)
      
          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>
          );
        }
      
    2. 错误更改为:children is undefined ....令人困惑。

      1. 将if条件更改为{? :}

        const children = { nodes ? <div>{nodes.map(node => <TreeNode info={node} actions={actions} />)}</div> : <div>no open</div> }
        

        语法错误:

        ERROR in ./src/containers/TreeNode.js
        Module build failed: SyntaxError: E:/Project/simple-redux-boilerplate/src/containers/TreeNode.js: Unexpected token (54:2
        9)
          52 |         // <div>{nodes.map(node => <TreeNode info={node} />)}</div>
          53 |
        > 54 |     const children = { nodes ? <div>{nodes.map(node => <TreeNode info={node} actions={actions} />)}</div> : <div>
        no open</div> }
             |                              ^
          55 |     return (
          56 |       <div className={classNames('tree-node', { 'open':this.props.open})} onClick={ () => {this.handleClick()} }>
        
      2. 最后 我在一个例子中看到了如下代码:

            {!user &&
            <div>
              <p>This will "log you in" as this user, storing the username in the session of the API server.</p>
            </div>
            }
            {user &&
            <div>
              <p>You are currently logged in as {user.name}.</p>
            </div>
            }
        

        所以我尝试使用:

        {nodes && <div>{nodes.map(node => <TreeNode info={node} />)}</div>
        }
        

        这很有效,但我不知道为什么......

        我查看if-else-in-JSX,与上述内容无关。

        我只是想知道为什么2,3不能正常工作,4使用的语法是什么,任何文档?

1 个答案:

答案 0 :(得分:2)

  

我只是想知道为什么2,3不能工作

2不起作用,因为const块范围。即children只能在ifelse块中访问。简化示例:

if (true) {
  const foo = 42;
  // foo is only visible inside this {...}
}
console.log(foo); // error

3不起作用,因为您以不应该使用的方式使用{...}{...}是块或对象文字,如果在JSX中使用,则标记表达式。您在赋值的RHS上使用它们,因此它们被解释为 object literal 。但{...}的内容对于对象文字无效,因此会出现语法错误。

您想要使用它们的原因仅适用于JSX。在JSX之外你不需要它们。这很好用:

const children = nodes ? <div>{nodes.map(node => <TreeNode info={node} actions={actions} />)}</div> : <div>no open</div>;
  

使用的语法4是什么,任何文档?

&&逻辑AND 运算符。这种方式有效,因为逻辑AND和OR返回表达式的最后一个求值。在您的情况下,如果数组中为nodes,则会转换为true,这意味着还必须评估右操作数(<div>...</div>)。
但如果nodesundefined(转换为false),则右操作数进行评估。

Read more about logical operators on MDNshort circuit evaluation

一些例子:

'' && 42    // ''
'foo' && 42 // 42

'' || 42    // 42
'foo' || 42 // 'foo'