#reactjs #handler
#reactjs #обработчик
Вопрос:
Это мой родительский компонент, имеющий состояние (значение и элемент). Я пытаюсь передать состояние значения в качестве реквизита дочернему компоненту. Код, выполняемый в методе рендеринга, выполняет переключение, когда я нажимаю на кнопку. Но когда я вызываю функцию списка внутри componentDidMount, переключение не работает, но выполняется событие щелчка.
import React, { Component } from 'react'
import Card from './Components/Card/Card'
export class App extends Component {
state = {
values : new Array(4).fill(false),
item : [],
}
toggleHandler = (index) => {
console.log("CLICKED");
let stateObject = this.state.values;
stateObject.splice(index,1,!this.state.values[index]);
this.setState({ values: stateObject });
}
list = () => {
const listItem = this.state.values.map((data, index) => {
return <Card key = {index}
show = {this.state.values[index]}
toggleHandler = {() => this.toggleHandler(index)} />
})
this.setState({ item : listItem });
}
componentDidMount(){
// if this is not executed as the JSX is render method is executed everything is working fine. as props are getting update in child component.
this.list();
}
render() {
return (
<div>
{/* {this.state.values.map((data, index) => {
return <Card key = {index}
show = {this.state.values[index]}
toggleHandler = {() => this.toggleHandler(index)} />
})
} */}
{this.state.item}
</div>
)
}
}
export default App
Это мой дочерний компонент, в котором состояние передается как реквизит
import React from 'react'
const Card = (props) => {
return (
<div>
<section>
<h1>Name : John Doe</h1>
<h3>Age : 20 </h3>
</section>
{props.show ?
<section>Skills : good at nothing</section> : null
}
<button onClick={props.toggleHandler} >Toggle</button>
</div>
)
}
export default Card
Я знаю, что componentDidMount выполняется только один раз. но как заставить его работать, кроме как писать JSX непосредственно внутри метода рендеринга
Комментарии:
1. Спасибо, Рехан, за ответ, таким образом, все работает правильно.
Ответ №1:
создайте копию состояния вместо того, чтобы изменять его напрямую. Используя […this.state.values] или this.state.values.slice()
toggleHandler = (index) => {
console.log("CLICKED");
let stateObject = [...this.state.values]
stateObject = stateObject.filter((_, i) => i !== index);
this.setState({ values: stateObject });
}
Также в вашем методе рендеринга this.state.item является массивом, поэтому вам нужно выполнить цикл
{this.state.item.map(Element => <Element />}
Также непосредственно в вашем методе рендеринга вы можете просто сделать
{this.state.values.map((data, index) => {
return <Card key = {index}
show = {this.state.values[index]}
toggleHandler = {() => this.toggleHandler(index)} />
})}
В вашем компоненте card попробуйте использовать
<button onClick={() => props.toggleHandler()}} >Toggle</button>
Комментарии:
1. Спасибо, Омар, за твой ответ, я внес все изменения, но вопрос в том, что обработчик переключения не работает, когда я отображаю {this.state.item.map(Элемент => <Элемент />} этот код вместо этого {this.state.values.map((данные, индекс)=> { return <Card key = {index} show = {this.state.values[index]} toggleHandler = {() => this.toggleHandler(index)} /> })} Можете ли вы, пожалуйста, подсказать мне, как заставить это работать с первым подходом. Еще раз спасибо.
2. да, я внес одно изменение в свой ответ, если это не решит проблему, я думаю, вам следует воспроизвести ошибку в codesandbox, чтобы я мог напрямую редактировать ваш код. Пожалуйста, взгляните на изменения, которые я внес в функцию toggleHandler Я использую array.filter вместо array.splice
3. codesandbox.io/s/frosty-bohr-v6hxw?file=/src/App.js ссылка на codesandbox
Ответ №2:
Значение должно быть отображено внутри render()
компонента класса, чтобы работать
вот так:
render() {
const { values } = this.state;
return (
<div>
{values.map((data, index) => {
return (
<Card
key={index}
show={values[index]}
toggleHandler={() => this.toggleHandler(index)}
/>
);
})}
</div>
);
}
проверьте песочницу для демонстрации
https://codesandbox.io/s/stupefied-spence-67p4f?file=/src/App.js