Я пытаюсь добавить состояние в некоторые динамические элементы управления пользовательского интерфейса, созданные с помощью ReactJS. Я получаю ошибку
Uncaught TypeError: _this.setState is not a function
Я в основном получил действительно хороший образец из пера рекурсивного генерирования элементов управления пользовательского интерфейса на основе некоторого JSON - я сделал их управляемыми компонентами (добавив значения / свойства в элементах управления).
Это все хорошо, однако ни один из элементов управления пользовательского интерфейса не обновляется (поэтому флажок не снимает флажок в пользовательском интерфейсе, если он изначально установлен). Поэтому, чтобы исправить это, я сейчас пытаюсь добавить к нему State, чтобы пользовательский интерфейс работал правильно. Я действительно не уверен, что это правильный путь или я должен просто сделать их все неконтролируемыми компонентами и использовать ссылки - но это, очевидно, не лучшая практика в соответствии с документацией реагирования.
Я добавил в onChange
событие на InputGroup
. Это вызывает inputChangedHandler
функцию, и в этом я пытаюсь setState
- вот где я получаю ошибку
Uncaught TypeError: _this.setState is not a function
в этой строке:
this.setState({ input: event.target.checked });
Я думаю, что причина, по которой он терпит неудачу на этом этапе, заключается в том, что на this
нет метода setState
, поэтому я не уверен, как пройти через правильное 'this'. Я инициализировал состояние внутри конструктора, что я считаю правильным решением. Я думаю, что это просто вопрос возможности использовать этот setState
метод на правильном this
.
//Component defined for text, date, numeric and checkbox)
const InputGroup = props => {
const types = { "Text": 'text', "Date": 'date', "Numeric": "number", "CheckBox": "checkbox" }
return (
//The props.value relates to JSX attribute names for the inputgroup below
<div className="input-groupDynamic">
<label className="labelD" htmlFor={props.label.replace(" ", "-")}>{props.label}</label>
<input name={props.label.replace(" ", "-")}
type={types[props.type]}
//uncontrolled components code
//defaultValue={props.value}
//defaultChecked={props.value}
//controlled components code
value={props.value}
checked={props.value}
onChange={this.inputChangedHandler.bind(this)}
/>
</div>
)
}
//arrow function
inputChangedHandler = (event) => {
if (event.target.type == 'checkbox') {
alert('new value : ' + event.target.checked);
this.setState({ saveCareersUrlVisible: event.target.checked });
} else {
alert('new value : ' + event.target.value);
}
}
//arrow function
inputChangedHandler = (event, data) => {
if (event.target.type == 'checkbox') {
this.setState({ input: event.target.checked });
} else {
//to do....
}
}
const renderChildren = children => {
//This is the bit that does a recursive-ish rendering of children....using the .map to map over the JSON data return children? children.map((child, ind) => {
//Using 'const' as the variable won’t be reassigned.
const newChildren = child.children ? [...child.children] : [];
const { containerType, title, input, label, options, value, ref } = child
//Using 'let' as this is a variable that may be reassigned
let key;
let actualDate;
if (typeof (input) !== 'undefined' && input == "Date" && typeof (value) !== 'undefined') {
//console.log("control type : " + input);
actualDate = new Date(value).toISOString().substr(0, 10);
}
//console.log("Date from JSON :" + (typeof (date) !== 'undefined' ? date : '2001-01-01'));
//console.log("Converted Date:" + test.toString());
//console.log("initial date value: " + date);
if (newChildren.length) {
key = `${containerType}-${ind}`;
switch (containerType) {
case "Tabs":
return <Tabs
key={key}
title={title}
children={newChildren}
/>
case "Column":
return <Column
key={key}
title={title}
children={newChildren}
/>
case "Row":
return <Row
key={key}
title={title}
children={newChildren}
/>
default:
return <Common
key={key}
title={title}
children={newChildren}
/>
}
} else {
console.log("control type : " + input);
console.log("ref : " + ref);
key = `${input}-${ind}`
console.log("key : " + key);
switch (input) {
case "ComboBox":
return <SelectGroup
key={key}
label={label}
options={options}
/>
case "Text":
case "Numeric":
return <InputGroup
key={key}
label={label}
type={input}
value={value}
//ref={ref}
/>
case "Date":
return <InputGroup
key={key}
label={label}
type={input}
value={actualDate}
//ref={key}
/>
case "CheckBox":
return <InputGroup
key={key}
label={label}
type={input}
value={value}
//onChange={e => this.setState({ SaveCareersUrlVisible: props.label.replace(" ", "-" + e.value) })}
/>
case "Button":
return <ButtonGroup
key={key}
type={input}
onClick={(e) => this.handleSubmitClick(e)}
></ButtonGroup>
}
}
}) : null
}
class App extends React.Component {
//Class constructor
constructor(props) {
// Pass props to the parent component
super(props)
// Set initial state, use spread notation and pass entire object (the JSON data in this case) - this will unpack it into the props
this.state = {
saveCareersUrlVisible: "",
...props.config
};
}
componentDidMount() {
alert("componentDidMount");
}
handleSubmitClick = (event) => {
event.preventDefault();
const data = new FormData(event.target);
this.setState({
myvalues: stringifyFormData(data),
});
}
render() {
const { title, children, saveCareersUrlVisible } = this.state;
return (
<Container title={title} children={children} saveCareersUrlVisible={saveCareersUrlVisible}/>
)
}
}
Я ожидаю, что смогу вызвать setState
(в какой-то момент), когда пользователь, например, нажимает на флажок, он повторно отображает состояние и обновляет пользовательский интерфейс - поэтому флажок снимает или проверяет в пользовательском интерфейсе .
То, что он на самом деле делает, это ошибка на setState
- так что влияние заключается в том, что пользовательский интерфейс не обновляется, даже если происходит событие onChange
, и я могу подобрать измененное значение. Примечание. Если полностью удалить настройку «состояние», пользовательский интерфейс не будет обновлен, поэтому я хочу добавить «состояние» в свое решение.