javascript - 如何将状态添加到动态 UI 控件中?
问题描述
我正在尝试为使用 ReactJS 创建的一些动态 UI 控件添加一些状态。我收到错误
Uncaught TypeError: _this.setState is not a function
我基本上从基于一些 JSON 的递归生成 UI 控件的笔中得到了一个非常好的示例——我已经将它们制成了受控组件(通过向控件添加值/检查属性)。
这一切都很好,但是,没有任何 UI 控件更新(因此,如果最初选中的复选框不会在 UI 中取消选中)。所以为了解决这个问题,我现在尝试向它添加状态,以便 UI 正常工作。我真的不确定这是否是正确的方法,或者我是否应该将它们全部设为不受控制的组件并使用参考 - 但根据反应文档,这显然不是最佳实践。
我已经onChange
在InputGroup
. 这调用inputChangedHandler
函数,在这我试图setState
- 这是我得到错误的地方
Uncaught TypeError: _this.setState is not a function
在这条线上:
this.setState({ input: event.target.checked });
我认为它在这一点上失败的原因是没有setState
方法,this
所以我不确定如何通过正确的“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
在用户(例如)单击复选框时(在某个时候)调用,它会重新呈现状态并更新 UI - 因此复选框取消选中或选中 UI。
它实际上在做的是错误setState
- 所以影响是 UI 没有更新,即使onChange
事件触发并且我可以获取更改的值。注意:如果我完全删除“状态”的设置,那么 UI 不会更新,这就是我想在我的解决方案中添加“状态”的原因。
解决方案
您正在打电话this.inputChangedHandler
,但请注意InputGroup
不是 aclass
而是 a function
。
此外,没有setState
内部常规函数,这是您通过创建class
扩展的方法获得的React.Component
简而言之,如果您想要setState
(或任何其他特定于反应的功能),您将需要使用 aclass
并从React.Component扩展
所以这或多或少应该是这样的:
class InputGroup extends React.Component {
state = { saveCareersUrlVisible: false } // initial state
//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);
}
}
render() {
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={this.props.label.replace(" ", "-")}>{this.props.label}</label>
<input name={this.props.label.replace(" ", "-")}
type={types[this.props.type]}
//uncontrolled components code
//defaultValue={props.value}
//defaultChecked={props.value}
//controlled components code
value={this.props.value}
checked={this.props.value}
onChange={this.inputChangedHandler.bind(this)}
/>
</div>
)
}
}
推荐阅读
- java - android 项目构建失败并出现异常。无法获取 Gradle 包装器属性
- javascript - 在 Shopify 中触发微调器数量按钮
- python - 清理 Docker pip install 导致错误:这些包与需求文件中的哈希不匹配
- tensorflow - Google Colab 中的 TensorFlow 版本选择
- rust - 如何快速从 HashSet 中查看任意值?
- ios - Swift 和 ZoomSDK,加入会议
- reporting-services - 数据集未在 SSRS 设计器中检索结果
- python - Discord.py 无法通过正确的频道 ID 找到频道
- java - 如何切换由下划线分隔的字符串的两个元素?
- javascript - 从服务器到客户端获取/获取数据的问题。(从客户端向服务器发送数据成功)