I want to pass a click handle (handleDeleteUser) to other component, from user.js to DropDownUserTool.js actually:
User.js
handleDeleteUser = (id) => {
alert(id);
};
...
// in render
User.data.map(function (User, i) {
return (
<DropDownUserTool
id={User.id}
click={(e) => {
this.handleDeleteUser(e);
}}
/>
);
});
DropDownUserTool.js
const DropDownUserTool = (props) => {
return (
<ButtonDropdown isOpen={dropdownOpen} toggle={toggle}>
<DropdownToggle color="secondary" caret>
tools
</DropdownToggle>
<DropdownMenu>
<DropdownItem>
<Link to={"/User/Edit/" + props.id}>Edit</Link>
</DropdownItem>
<DropdownItem onClick={() => props.click(props.id)}>
Delete
</DropdownItem>
</DropdownMenu>
</ButtonDropdown>
);
};
But after click it return an error:
TypeError: Cannot read properties of undefined (reading 'handleDeleteUser')
On this line:
<DropDownUserTool id={User.id} click={(e) => {this.handleDeleteUser(e)}}/>
You are trying to reach this inside map, just define this ! inside render before loop:
let realthis = this;
Then call your handler like this:
<DropDownUserTool id={User.id} click={(e) => {realthis.handleDeleteUser(e)}}/>
When you're doing your map you're using a standard function call and losing your context. Use an arrow function instead.
class User extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [{ id: 1 }, { id: 2 }, { id: 3 }]
};
}
handleDeleteUser = (id) => alert(id);
render() {
return (
<div>
// this needs to be an arrow function
// that way you won't change the context of `this`
{this.state.data.map((item, i) => {
return (
<DropDownUserTool
id={item.id}
key={item.id}
handleDelete={this.handleDeleteUser }
/>
);
})}
</div>
);
}
}
const DropDownUserTool = ({ handleDelete, id }) => (
<button onClick={() => handleDelete(id)}>Delete</button>
);