2

I have a react component which represents a row in a table of words. It re-renders when the state changes, but it does not update onClick event handler. I have stripped down the component to the bare minimum and it still has the issue. When I click the "Edit" link, the console prints "onEdit" and the state appears to look correct in the browser, but then when I click "Revert", the console prints "onEdit" a second time. Why is the onClick event not being updated to use the _onRevert function after the state changes? Why it is still hanging on to the old event handler from the first render pass? Thank you.

var React = require('React/addons');

var WordListItem = React.createClass({
    getInitialState: function(){
        return {
            isEditing: false,
            english: this.props.word.english
        };
    },
    _onEdit: function(e) {
        e.preventDefault();
        console.log('onEdit');
        this.setState({isEditing: true});
    },
    _onRevert: function(e){
        e.preventDefault();
        console.log('onRevert');
        this.setState({isEditing: false});
    },
    render: function() {
        if(this.state.isEditing) {
            return (
                <div>
                    <span>Editing: {this.state.english} </span>
                    <a href="#" onClick={this._onRevert}>Revert</a>
                </div>
            )
        } else {

            return (
                <div>
                    <span>Not Editing: {this.state.english} </span>
                    <a href="#" onClick={this._onEdit}>Edit</a>
                </div>
            )
        }

    }
})

module.exports = WordListItem;

UPDATE BELOW

So it turns out that it works if I paste this component into my main app.jsx file, it works, but not if I include it using require js. Which is weird, because browserify is working since I can still include other files and compose nested react components, it just that it the events don't get updated on some elements. Maybe at this point I should ask a new question, which is more focused.

    var React = require('react/addons');
//var materialize = require('materialize-css');
var word = {id: 4671810846, english: "water", persian: "آب", phonetic: "aab", tags: ["noun","food","drink"]};

var WordListItem = require('./components/wordList/WordListItem.jsx');

// var WordListItem = React.createClass({
//     getInitialState: function(){
//         return {
//             isEditing: false,
//             english: this.props.word.english
//         };
//     },
//     _onEdit: function(e) {
//         e.preventDefault();
//         console.log('onEdit');
//         this.setState({isEditing: true});
//     },
//     _onRevert: function(e){
//         e.preventDefault();
//         console.log('onRevert');
//         this.setState({isEditing: false});
//     },
//     render: function() {
//         if(this.state.isEditing) {
//             return (
//                 <div>
//                     <span>Editing: {this.state.english} </span>
//                     <a href="#" onClick={this._onRevert}>Revert</a>
//                 </div>
//             )
//         } else {
//
//             return (
//                 <div>
//                     <span>Not Editing: {this.state.english} </span>
//                     <a href="#" onClick={this._onEdit}>Edit</a>
//                 </div>
//             )
//         }
//
//     }
// })


React.render(<WordListItem word={word}/>, document.getElementById('app'));
13
  • console.log "this" inside of the function call for _onEdit, and then console.log the state of isEditing. Are you sure your context is correct inside of that function? Commented May 26, 2015 at 0:36
  • Well that is interesting. When I log this and click Edit and then click Revert, both _onEdit and _onRevert handlers log the same this object, and the state of isEditing is set to true inside this object. However, this.state.isEditing first prints false, and then it prints true. Commented May 26, 2015 at 0:42
  • well, at least there's the real issue. Your code works, but it looks like the inital state is getting set again. Commented May 26, 2015 at 0:45
  • I put a print statement in the getInitialState function, and it only gets called once for each copy of this component and never gets called again, even after clicking the links. Commented May 26, 2015 at 0:50
  • The code you've posted seems to work fine as-is; see jsfiddle.net/BinaryMuse/3zeb0gdo I also see alternating console.logs of "onEdit" and "onRevert", as expected. Commented May 26, 2015 at 3:04

1 Answer 1

2

Can you show the way you are rendering this child component in a parent ? I have a suspicion that when you are generating an array of WordListItem's you are not setting a key property (or using a simple index as key property, which is a recipe for disaster if you are also removing WordListItem's, the key has to be unique.

Also i think this component would be better if it didn't have state at all, have state on top parent component instead and send props down to children.

EDIT:

In your word_list_item.jsx file, you require react as var React = require('React/addons'); Is this just a typo you made when you were pasting code ? It should be var React = require('react/addons') with lower case letters. Just a small observation, not sure if this has to do with anything, but sure looks like you have some kind of browserify issue.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the suggestions. I definitely set a unique key in a list of them. Also, the state is useful, just maybe not for this stripped down version.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.