【问题标题】:Avoid cannot read property 'map' of undefined in react redux避免在反应 redux 中无法读取未定义的属性“映射”
【发布时间】:2016-10-22 10:07:12
【问题描述】:

我看到了一些类似 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?

这是说 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>
        );
      }
    

错误更改为:children is undefined ....confusing。

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

    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()} }>
    

最后 4. 我在一个例子中看到了一些类似下面的代码:

    {!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 是什么,任何文档?

【问题讨论】:

  • 顺便说一句,如果你想在组件类中初始化状态,你只需要在构造函数中初始化它:constructor(props) { ..., this.state = {your_state}}

标签: javascript reactjs redux


【解决方案1】:

我只是想知道为什么 2、3 不起作用

2 不起作用,因为consts 是块作用域。 IE。 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 是什么,有什么文档吗?

&amp;&amp;逻辑与 运算符。这种方式有效,因为逻辑 AND 和 OR 返回表达式的最后评估值。在您的情况下,如果 nodes 在数组中,它将转换为 true,这意味着还必须评估正确的操作数 (&lt;div&gt;...&lt;/div&gt;)。
但如果nodesundefined(转换为false),则计算右操作数。

Read more about logical operators on MDNshort circuit evaluation.

一些例子:

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

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

【讨论】:

  • 我从来没有使用&amp;&amp; 来返回最后一个值,总是在条件下使用。学习新知识,谢谢~
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 2016-12-05
  • 2023-03-13
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多