J'ai écrit ce code et je suis actuellement aux prises avec un bogue dans un événement onClick. J'ai deux événements, l'événement onClick sur l'élément enfant et l'événement onChange sur l'élément parent de niveau supérieur.
Le comportement attendu doit être de modifier la variable activeAccount actuellement détenue dans le composant Container. Pour ce faire, j'ai ajouté un gestionnaire onClick sur le composant AccountRow qui devrait ensuite appeler la fonction onChange du parent de niveau supérieur.
Cependant, la ligne
'this.props.onChange(this.props.account)',
dans
handleClick: function(e) {
this.props.onChange(this.props.account);
},
destiné à appeler la fonction parent avec le paramètre 'this.props.account',
me donne cette erreur:
Uncaught TypeError: this.props.onChange is not a function.
J'ai d'abord pensé qu'il s'agissait d'un problème de portée, mais j'ai ajouté
{...this.props}
sur chaque enfant et enfant imbriqué dans le composant Container parent. Ainsi, tous les accessoires auraient dû être propagés jusqu'au composant AccountRow. Néanmoins, le problème persiste.
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);
Merci pour votre temps.
Le problème est causé par la fonction map
, vous devez passer this
pour thisArg
lors de l'appel de map
:
this.props.accounts.map(function(each_account) {
rows.Push(
<AccountRow
account = {each_account.name}
key = {each_account.name}
{...this.props}
/>);
}, this);
Cependant, cela entraînera pour AccountRow
des variables redondantes comme accounts
et activeAccount
. Je pense que vous devriez envisager de transférer uniquement la fonction onChange
:
<AccountRow
account = {each_account.name}
key = {each_account.name}
onChange = {this.props.onChange}
/>