简体   繁体   English

当单击项目时如何更改reactJS中列表中项目的所有值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM