ReactJS:“this.props"当子组件调用父组件时不是函数 [英] ReactJS: "this.props" is not a function when child component calls parent
问题描述
我已经编写了这段代码,目前正在处理 onClick 事件中的错误.我有两个事件,子元素上的 onClick 事件和顶级父元素上的 onChange 事件.
预期的行为应该是更改当前保存在 Container 组件中的 activeAccount 变量.为此,我在 AccountRow 组件上添加了一个 onClick 处理程序,然后该处理程序应该调用顶级父级的 onChange 函数.
然而,行
'this.props.onChange(this.props.account)',
在
handleClick: function(e) {this.props.onChange(this.props.account);},
意思是调用带有参数'this.props.account'的父函数,
给我这个错误:
未捕获的类型错误:this.props.onChange 不是函数.
我最初认为这是一个范围界定问题,但我已添加
{...this.props}
在父容器内的每个子节点和嵌套子节点上成分.因此,所有道具都应该向下传播到 AccountRow 组件.尽管如此,问题仍然存在.
var ACCOUNTS = [{name: '手头现金'},{name: '储蓄账户'},{名称:'共享帐户'},{名称:'我的第二个钱包'}];无功交易 = [{日期:'',名称:'香蕉',数量:6,类别:'杂货',账户:'手头现金'},{日期:'',名称:'苹果',数量:2.50,类别:'杂货',账户:'手头现金'},{日期:'',姓名:'提现',金额:250,账户:'储蓄账户'}];var AccountRow = React.createClass({句柄点击:函数(e){this.props.onChange(this.props.account);},渲染:函数(){返回 (<li onClick = {this.handleClick}>{this.props.account}</li>)}});var AccountList = React.createClass({渲染:函数(){var 行 = [];this.props.accounts.map(function(each_account) {行.推(<账户行帐户 = {each_account.name}键 = {each_account.name}{...this.props}/>);})返回 (<ul>{行})}});var NavBar = React.createClass({渲染:函数(){返回 (<div id = '账户标签'><h2>帐户<账户列表帐户 = {this.props.accounts}{...this.props}/>
)}});var TransactionRow = React.createClass({渲染:函数(){var trans = this.props.transaction;返回 (<tr><td>{trans.date}</td><td>{trans.name}</td><td>{trans.amount}</td><td>{trans.account}</td><td><a href = ''>edit</a></td></tr>)}});var TransactionList = React.createClass ({渲染:函数(){var activeaccount = this.props.activeAccount;var 行 = [];this.props.transactions.map(function(each_transaction) {if (each_transaction.account == activeaccount) {/* 非常奇怪的行为if (each_transaction account == this.props.activeAccount)不起作用,我不知道为什么会这样*/rows.push(<TransactionRow transaction = {each_transaction} key = {each_transaction.name}/>);}别的 {/*console.log(each_transaction.account);*/}})返回 (
{行}</tbody>)}});var TransactionsTable = React.createClass({渲染:函数(){返回 (<div id = '最近交易'><h2>{this.props.activeAccount}</h2>的最近交易<表格><tr><第>日期</th><th>name</th><th>数量</th><第>帐户</th><th>编辑</th></tr><事务列表交易 = {this.props.transactions}activeAccount = {this.props.activeAccount}/>)}});var TransactionForm = React.createClass({渲染:函数(){返回 (<div><h2>添加交易</h2><p>交易名称</p><输入类型 = '文本'/><p>价格</p><输入类型 = '数字'/><p>类别(可选)</p><输入类型 = '文本'/>
)}});var ButtonMenu = React.createClass ({渲染:函数(){返回 (<div><button>添加交易</button>
)}});var Container = React.createClass({getInitialState: 函数 (){返回 {activeAccount: ACCOUNTS[0].name};},setActiveAccount:函数(数据){this.setState({活动帐户:dat});},渲染:函数(){返回 (<div id = '包装器'><导航栏帐户 = {帐户}activeAccount = {this.state.activeAccount}onChange = {this.setActiveAccount}{...this.props}/><交易表交易 = {交易}activeAccount = {this.state.activeAccount}/><交易表格/><按钮菜单/>
);}});React.render(
感谢您抽出宝贵时间.
问题是由map
函数引起的,你应该为thisArg<传入
this
/code> 调用 map
时:
this.props.accounts.map(function(each_account) {行.推(<账户行帐户 = {each_account.name}键 = {each_account.name}{...this.props}/>);}, 这);
然而,这会导致 AccountRow
有像 accounts
和 activeAccount
这样的冗余变量.我认为你应该考虑只传输 onChange
函数:
I have written this code and am currently wrangling with a bug in an onClick event. I have two events, the onClick event on the child element and the onChange event on the top-level parent element.
The expected behaviour should be to change the activeAccount variable currently held in the Container component. To do this, I added an onClick handler on the AccountRow component that should then call the top-level parent's onChange function.
However, the line
'this.props.onChange(this.props.account)',
in
handleClick: function(e) {
this.props.onChange(this.props.account);
},
meant to call the parent function with parameter 'this.props.account',
gives me this error:
Uncaught TypeError: this.props.onChange is not a function.
I initially thought that this was a scoping issue, but I have added
{...this.props}
on every child and nested child within the parent Container component. So, all props should have been propagated down to the AccountRow component. Nevertheless, the problem still remains.
var ACCOUNTS = [
{name: 'cash on hand'},
{name: 'savings account'},
{name: 'shared account'},
{name: 'my second wallet'}
];
var TRANSACTIONS = [
{date: '', name: 'Bananas', amount: 6, category: 'Groceries', account: 'cash on hand'},
{date: '', name: 'Apples', amount: 2.50, category: 'Groceries', account: 'cash on hand'},
{date: '', name: 'Cash withdrawal', amount: 250, account: 'savings account'}
];
var AccountRow = React.createClass({
handleClick: function(e) {
this.props.onChange(this.props.account);
},
render: function () {
return (
<li onClick = {this.handleClick}> {this.props.account}</li>
)}
});
var AccountList = React.createClass({
render: function () {
var rows = [];
this.props.accounts.map(function(each_account) {
rows.push(
<AccountRow
account = {each_account.name}
key = {each_account.name}
{...this.props}
/>);
})
return (
<ul>
{rows}
</ul>
)
}
});
var NavBar = React.createClass({
render: function () {
return (
<div id = 'account-tabs'>
<h2> Accounts </h2>
<AccountList
accounts = {this.props.accounts}
{...this.props}
/>
</div>
)
}
});
var TransactionRow = React.createClass({
render: function (){
var trans = this.props.transaction;
return (
<tr>
<td>{trans.date}</td>
<td>{trans.name}</td>
<td>{trans.amount}</td>
<td>{trans.account}</td>
<td><a href = ''>edit</a></td>
</tr>
)
}
});
var TransactionList = React.createClass ({
render: function () {
var activeaccount = this.props.activeAccount;
var rows = [];
this.props.transactions.map(function(each_transaction) {
if (each_transaction.account == activeaccount) {
/* Very strange behaviour
if (each_transaction account == this.props.activeAccount)
DOES NOT WORK, I do not know why this is the case
*/
rows.push(<TransactionRow transaction = {each_transaction} key = {each_transaction.name} />);
}
else {
/*console.log(each_transaction.account);*/
}
})
return (
<tbody>
{rows}
</tbody>
)
}
});
var TransactionsTable = React.createClass({
render: function() {
return (
<div id = 'recent-transactions'>
<h2>Recent Transactions for {this.props.activeAccount}</h2>
<table>
<tr>
<th>date</th>
<th>name</th>
<th>amount</th>
<th>account</th>
<th>edit </th>
</tr>
<TransactionList
transactions = {this.props.transactions}
activeAccount = {this.props.activeAccount}
/>
</table>
</div>
)
}
});
var TransactionForm = React.createClass({
render: function() {
return (
<div>
<h2>Add Transaction </h2>
<p>Transaction name</p>
<input type = 'text' />
<p>Price</p>
<input type = 'number'/>
<p>Category (optional) </p>
<input type = 'text' />
</div>
)
}
});
var ButtonMenu = React.createClass ({
render: function () {
return (
<div>
<button>Add Transaction</button>
</div>
)
}
});
var Container = React.createClass({
getInitialState: function (){
return {
activeAccount: ACCOUNTS[0].name
};
},
setActiveAccount: function(dat) {
this.setState({
activeAccount: dat
});
},
render: function () {
return (
<div id = 'wrapper'>
<NavBar
accounts = {ACCOUNTS}
activeAccount = {this.state.activeAccount}
onChange = {this.setActiveAccount}
{...this.props}
/>
<TransactionsTable
transactions = {TRANSACTIONS}
activeAccount = {this.state.activeAccount}
/>
<TransactionForm />
<ButtonMenu />
</div>
);
}
});
React.render(<Container />, document.body);
Thank you for your time.
The problem is caused by map
function, you should pass in this
for thisArg
when calling map
:
this.props.accounts.map(function(each_account) {
rows.push(
<AccountRow
account = {each_account.name}
key = {each_account.name}
{...this.props}
/>);
}, this);
However, this will cause AccountRow
to have redundant variables like accounts
and activeAccount
. I think you should consider transfer only the onChange
function:
<AccountRow
account = {each_account.name}
key = {each_account.name}
onChange = {this.props.onChange}
/>
这篇关于ReactJS:“this.props"当子组件调用父组件时不是函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!