我看到了一些像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
,我知道节点可能未定义。
我试过了
添加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不能在组件中使用。
更改渲染以使用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
....令人困惑。
将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()} }>
最后 我在一个例子中看到了如下代码:
{!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使用的语法是什么,任何文档?
答案 0 :(得分:2)
我只是想知道为什么2,3不能工作
2不起作用,因为const
是块范围。即children
只能在if
和else
块中访问。简化示例:
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>
)。
但如果nodes
为undefined
(转换为false
),则右操作数不进行评估。
Read more about logical operators on MDN和short circuit evaluation。
一些例子:
'' && 42 // ''
'foo' && 42 // 42
'' || 42 // 42
'foo' || 42 // 'foo'