I have a react app in which I am supposed to get users from an API endpoint: <reqres.in>.
I am supposed to return as many buttons on the homepage as the number of users I get on fetching the users from the API.
Also I am constrained not to add event listeners to all buttons and just add one listener to the wrapper for the buttons. The code for the same is:
const ButtonContainer = ({ users }) => {
// const navigate=useNavigate();
const wrapper = document.getElementById('wrapper');
wrapper.addEventListener('click', (event) => {
const isButton = event.target.nodeName === 'BUTTON';
if (!isButton) {
return;
}
// navigate(`/singleuser/${event.target.id}`);
})
return (
<div id='wrapper'>
{
users.map((user, idx) => {
return (
<button key={idx} id={idx}>
User {idx}
</button>
)
})
}
</div>
)
}
export default ButtonContainer
users is the array of users Im getting from the API.
However I am getting the error:
Cannot read properties of null (reading 'addEventListener')
What should I do?
CodePudding user response:
Using native DOM methods with React won't give you the result you want as React has its own way of managing the DOM.
Add an onClick
to your wrapper element:
<div onClick={handleClick}>
and then have handleClick
deal with the event.
function Example({ users }) {
function handleClick(e) {
// Because we're using event delegation [1]
// check if the clicked element was a user button
if (e.target.matches('button.user')) {
// Extract the id from its dataset,
// and log it
const { id } = e.target.dataset;
console.log(`User: ${id}`);
}
}
return (
<div onClick={handleClick}>
{users.map(user => {
return (
<button
key={user.id}
className="user"
data-id={user.id}
>User: {user.id}
</button>
);
})}
</div>
);
}
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
ReactDOM.render(
<Example users={users} />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>