#reactjs
Вопрос:
Однако я не могу найти основную причину того, почему событие onChange не запускается после изменения проверки, однако при первой загрузке компонента вызывается onChange.
Я подготовил CodeSandbox с некоторыми образцами данных.
Вот компонент ,
import React from "react";
import styled from "styled-components";
import { checklists } from "./checklists";
import { questions } from "./questions";
const RadioOption = styled.input`
margin: 10px;
width: 16px;
height: 16px;
`;
const RadioGroup = (props) => {
return React.Children.map(props.children, (child) => {
if (child.type === RadioOption)
return React.cloneElement(child, {
type: "radio",
defaultChecked: props.value === child.props.value,
name: props.name,
disabled: props.disabled,
onChange: props.handleChange
});
return child;
});
};
class RadioGroupDemo extends React.Component {
state = {
checklist: "test_checklist_checklist",
questions: questions,
checklists: checklists
};
constructor(props) {
super(props);
this.onRadioChange = this.onRadioChange(this);
this.keyCount = 0;
this.getKey = this.getKey.bind(this);
}
onRadioChange = (e) => {
debugger;
console.log("handleRadios", e);
//let q = this.state.questions;
};
getKey() {
return this.keyCount ;
}
//first render
render() {
console.log(this.state.checklists);
return (
<div style={{ maxHeight: "600px", overflow: "auto" }}>
{this.state.checklist amp;amp;
this.state.checklists.questions[this.state.checklist].map(
(question) => {
//debugger;
let question_id = question.question_id;
return (
<div key={`${this.state.checklist}_${question.id}`}>
{question.title}
<div style={{ width: "120px", flex: "0 0 120px" }}>
{(() => {
if (
typeof this.state.questions[question.id] !== "undefined"
) {
return (
<RadioGroup
name={`field_question_${question.id}`}
disabled={this.state.readOnly}
value={
typeof this.state.questions[question.id].answer ==
"undefined"
? this.state.questions[question.id].answer
: Object.keys(this.state.questions)
.reduce(
(arr, key) =>
arr.concat(this.state.questions[key]),
[]
)
.find((q) => {
return q.question_id === question_id;
}).answer
}
onChange={this.onRadioChange}
>
<RadioOption key={this.getKey()} value="yes" />
<RadioOption key={this.getKey()} value="no" />
<RadioOption key={this.getKey()} value="na" />
</RadioGroup>
);
}
})()}
</div>
</div>
);
}
)}
</div>
);
}
}
export default RadioGroupDemo;
Пожалуйста, взгляните на codesandbox и скажите мне, почему событие не срабатывает.
Спасибо
Ответ №1:
Вопрос
Вы передаете onChange
реквизит RadioGroup
, но получаете доступ handleChange
к реквизиту, которого не существует.
const RadioGroup = (props) => {
return React.Children.map(props.children, (child) => {
if (child.type === RadioOption)
return React.cloneElement(child, {
type: "radio",
defaultChecked: props.value === child.props.value,
name: props.name,
disabled: props.disabled,
onChange: props.handleChange, // <-- accessed as handleChange
});
return child;
});
};
В компоненте
<RadioGroup
name={`field_question_${question.id}`}
disabled={this.state.readOnly}
value={
typeof this.state.questions[question.id].answer ==
"undefined"
? this.state.questions[question.id].answer
: Object.keys(this.state.questions)
.reduce(
(arr, key) =>
arr.concat(this.state.questions[key]),
[]
)
.find((q) => {
return q.question_id === question_id;
}).answer
}
onChange={this.onRadioChange} // <-- passed as onChange
>
В RadioGroupDemo
вас также нет привязки this
к onRadioChange
обработчику. Однако в этой привязке нет необходимости, поскольку onRadioChange
она объявлена как функция со стрелкой, this
привязывается автоматически.
constructor(props) {
super(props);
this.onRadioChange = this.onRadioChange(this); // <-- here
this.keyCount = 0;
this.getKey = this.getKey.bind(this);
}
Решение
Удалите попытку привязки this
к обработчику в конструкторе.
constructor(props) {
super(props);
this.keyCount = 0;
this.getKey = this.getKey.bind(this);
}
Получите доступ к правильной опоре.
const RadioGroup = (props) => {
return React.Children.map(props.children, (child) => {
if (child.type === RadioOption)
return React.cloneElement(child, {
type: "radio",
defaultChecked: props.value === child.props.value,
name: props.name,
disabled: props.disabled,
onChange: props.onChange // <-- onChange
});
return child;
});
};
Ответ №2:
Потому что в RadioOption
. Вы используете props.handleChange
Итак RadioGroupDemo
, просто обновите onChange
до handleChange
<RadioGroup
...
handleChange={this.onRadioChange}
>