在输入字段更改时,将调用处理程序函数并更新状态,但状态并未更新。我知道setState()
是异步的,所以我将console.log
放在了回调中。
以下是功能:
class WorkspaceEditModal extends React.PureComponent {
constructor(props) {
super(props);
console.log(props.selectedWorkspace); // prints correct value
this.state = {
editWorkspaceName: props.selectedWorkspace,
exists: false,
};
}
handleEditChange = event => { // this handler is called
console.log(event.target.value); // prints new value
this.setState({ editWorkspaceName: event.target.value },
() => {console.log(this.state.editWorkspaceName)}); // still prints old value
};
handleFocus = e => e.target.select();
handleKeyPress = e => {
if (e.key === 'Enter') {
e.preventDefault();
this.editWorkspace();
}
};
render() {
const { editWorkspaceName, exists } = this.state;
let content;
content = (
<div className="save-workspace">
<div className="modal-header">
<div className="modal-title">
<p>Rename Workspace</p>
</div>
<div className="modal-select">
<span className="input-label">Workspace Name</span>
<div>
<input
className="name-input"
placeholder="Workspace Name"
type="text"
defaultValue={editWorkspaceName}
onChange={this.handleEditChange} // calls the handler on change
onFocus={this.handleFocus}
onKeyPress={this.handleKeyPress}
autoFocus
/>
{notValid && (
<p className="invalid">
Only alphanumeric characters, hyphens, spaces, and
underscores are allowed.
</p>
)}
</div>
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-default"
onClick={this.onCloseModal}
>
Cancel
</button>
<button
type="button"
className="btn btn-primary"
onClick={this.editWorkspace}
disabled={notValid}
>
Update
</button>
</div>
</div>
);
const contentStyle = {
width: '500px',
};
return (
<Modal
isOpen={true}
onClose={this.onCloseModal}
contentStyle={contentStyle}
shouldCloseOnOverlayClick={true}
>
{content}
</Modal>
);
}
}
我不知道为什么会这样。这太疯狂了。
谢谢您的帮助。
答案 0 :(得分:-2)
您正在通过props传递输入的默认值。那应该是您输入的默认值。它不应更新子组件的状态。
状态应在父组件而不是子组件上更新。 handleEditChange(在示例中为handleChange)函数应放在父组件中,然后通过props向下传递到输入。您希望通过该父函数在props中更改props的值,以便setState正常工作。
您可以使用getDerivedStateFromProps,但是这里似乎没有必要。 https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
class ParentWorkSpaceEditModal extends React.Component {
constructor(props) {
super(props);
this.state = {
editWorkspaceName: 'whatever your original value is',
exists: false,
};
}
handleChange = event => {
this.setState({ editWorkspaceName: event.target.value });
};
render() {
const { editWorkspaceName, exists } = this.state;
return (
<ChildWorkspaceEditModal editWorkspaceName={editWorkspaceName} exists={exists} handleChange={this.handleChange} />
)
}
}
const ChildWorkspaceEditModal = ({ editWorkspaceName, exists, handleChange )} => {
content = (
<div className="save-workspace">
<div className="modal-header">
<div className="modal-title">
<p>Rename Workspace</p>
</div>
<div className="modal-select">
<span className="input-label">Workspace Name</span>
<div>
<input
className="name-input"
placeholder="Workspace Name"
type="text"
value={editWorkspaceName}
onChange={handleChange}
/>
{notValid && (
<p className="invalid">
Only alphanumeric characters, hyphens, spaces, and underscores are allowed.
</p>
)}
</div>
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-default"
onClick={this.onCloseModal}
>
Cancel
</button>
<button
type="button"
className="btn btn-primary"
onClick={this.editWorkspace}
disabled={notValid}
>
Update
</button>
</div>
</div>
);
const contentStyle = {
width: '500px',
};
return (
<Modal
isOpen={true}
onClose={this.onCloseModal}
contentStyle={contentStyle}
shouldCloseOnOverlayClick={true}
>
{content}
</Modal>
)
}