[英]How to change all value of items in a list in reactJS when onClick on an item
http://jsfiddle.net/adamchenwei/3rt0930z/23/ I tried apply solution from here react.js call parent function from child http://jsfiddle.net/adamchenwei/3rt0930z/23/我尝试从此处应用解决方案react.js从子级调用父函数
But I encounter issue: 3VM606:43Uncaught TypeError: Cannot read property 'changeName' of undefined
但是我遇到问题:
3VM606:43Uncaught TypeError: Cannot read property 'changeName' of undefined
Anyone knows why this is happening and how to fix it so that the onClick will change the name on every item, instead of just the one that got clicked on? 任何人都知道为什么会发生这种情况以及如何解决它,以便onClick会更改每个项目的名称,而不仅仅是单击的名称?
var items = [
{ name: 'Believe In Allah', link: 'https://www.quran.com' },
{ name: 'Prayer', link: 'https://www.quran.com' },
{ name: 'Zakat', link: 'https://www.quran.com' },
{ name: 'Fasting', link: 'https://www.quran.com' },
{ name: 'Hajj', link: 'https://www.quran.com' },
];
var ItemModule = React.createClass({
getInitialState: function() {
return { newName: this.props.name }
},
changeItsName() {
this.props.changeTheName();
},
render() {
//<!-- <a className='button' href={this.props.link}>{this.props.name}</a> -->
return (
<li onClick={this.changeItsName}>
{this.state.newName}
</li>
);
}
});
var RepeatModule = React.createClass({
getInitialState: function() {
return { items: [] }
},
changeName() {
console.log('changed name');
this.setState({ newName: 'Test' });
},
render: function() {
var listItems = this.props.items.map(function(item) {
return (
<div>
<ItemModule
name={item.name}
changeTheName={this.changeName.bind(this)}/>
</div>
);
});
return (
<div className='pure-menu'>
<h3>Islam Pillars</h3>
<ul>
{listItems}
</ul>
</div>
);
}
});
ReactDOM.render(<RepeatModule items={items} />,
document.getElementById('react-content'));
Thanks! 谢谢!
you have a scoping issue, within the map function this
is referencing the map function not your react object. 您有一个范围问题,在map函数中,
this
是引用map函数而不是您的react对象。 Either use es6 arrow syntax if you are using a transpiler or do the following 如果使用的是Transpiler,请使用es6箭头语法,或者执行以下操作
var self = this;
var listItems = this.props.items.map(function(item) {
return (
<div>
<ItemModule
name={item.name}
changeTheName={self.changeName}/>
</div>
);
});
The ES6 way of doing it would be: ES6的实现方式是:
var listItems = this.props.items.map((item) =>
<div>
<ItemModule
name={item.name}
changeTheName={this.changeName}/>
</div>
);
There is no need to do the this.changeName.bind(this)
either, it actually makes react less performant when you do bindings within a components prop. 也不需要执行
this.changeName.bind(this)
,当您在组件prop中进行绑定时,它实际上会使反应性能降低。 see: https://daveceddia.com/avoid-bind-when-passing-props/https://daveceddia.com/avoid-bind-when-passing-props/ 参见: https : //daveceddia.com/avoid-bind-when-passing-props/https : //daveceddia.com/avoid-bind-when-passing-props/
did you mean this -> http://codepen.io/dagman/pen/JRbyLj 你的意思是这个-> http://codepen.io/dagman/pen/JRbyLj
const items = [{
name: 'Believe In Allah',
link: 'https://www.quran.com'
}, {
name: 'Prayer',
link: 'https://www.quran.com'
}, {
name: 'Zakat',
link: 'https://www.quran.com'
}, {
name: 'Fasting',
link: 'https://www.quran.com'
}, {
name: 'Hajj',
link: 'https://www.quran.com'
}, ];
const ItemModule = ({
name,
changeName
}) => (
<li onClick={changeName}>
{name}
</li>
);
const RepeatModule = React.createClass({
getInitialState: function() {
return {
newName: ''
}
},
changeName() {
console.log('changed name');
this.setState({
newName: 'Test'
});
},
render() {
const listItems = this.props.items.map((item) => {
return (
<ItemModule
name={this.state.newName || item.name}
changeName={this.changeName.bind(this)}
/>
);
});
return (
<div className='pure-menu'>
<h3>Islam Pillars</h3>
<ul>
{listItems}
</ul>
</div>
);
}
});
ReactDOM.render(
<RepeatModule items={items} />,
document.getElementById('react-content')
):
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.