1

My scenario is: I have a list of items, and each render a component. Each time one of these items is clicked, I render yet another component (much like a modal) passing the current item as props. Inside the modal component there's on button that, when clicked, should trigger back a function on the component that created it.

My items are:

const items = [
    {
        id: 1,
        data: "some data"
    }, {
        id: 2,
        data: "some data"
    }, {
        id: 3,
        data: "some data"
    }
]

The dynamic creation of each item as a component:

items.map(item => {
                return { key: item.id, content: <Item key={item.id} ItemObject={item}/> }
            });

So far so good. Inside that Item component class I have three actions that concern this question: the first is called when the Item div is clicked, the other is the item's componentDidUpdate lifecycle method, and the third, called updateStatus update the component state. Here's the class:

Item.js

export function _updateStatus(newFlags) {
    this.setState({ flags: newFlags });
}

export default class SystemUnit extends React.Component {
    constructor(props) {
        super(props);
        this.state = { flags: [] };
        _updateStatus = _updateStatus.bind(this);
        this.handleClick = this.handleClick.bind(this);
    }
    handleClick() {
        ReactDOM.render(<Actions Item={this.props.ItemObject} />, document.getElementsByClassName("actions-wrapper")[0]);
    }
}

In the Actions component there's a button that, when clicked, should trigger back the updateStatus inside the Item that called Actions.

Actions.js

import { _updateStatus } from './Item';

export default class Actions extends React.Component {
    constructor(props) {
        super(props);
    this.state = {flags: []}
    }
    render() {
        <button onClick={() => { _updateStatus(this.state.flags) }}>Finish</button>
    }
}

However, the button triggers the method on the last item of the list, not on the component that rendered it. On this example I have three items, and no matter which one is clicked the Action component button will always trigger the cange on item 3.

How do I specify for the Action component that the updateStatus method should be triggered on the Item component that rendered it?

1 Answer 1

1

You import the function from the component itself via the line:

import { _updateStatus } from './Item';

This is why you are getting the function of the last rendered Item

Instead try passing the function as a param:

 ReactDOM.render(<Actions Item={this.props.ItemObject} updateStatus={this._updateStatus} />, document.getElementsByClassName("actions-wrapper")[0]);

And access in Actions like:

render() {
    <button onClick={() => { this.props.updateStatus(this.state.flags) }}>Finish</button>
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! That did it. Importing the function from the component itself is something I saw in some forum. This way is much cleaner, though.
Yep, use the power of the props. Happy coding!

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.