Подъём состояния при условном рендеринге в React.js
У меня есть форма, в которой в зависимости от условия рендерится инпут для поиска или для добавления нового пользователя. Если я выношу инпут для добавления за пределы условия, то состояние изменяется, иначе - нет. Подскажите, как решить проблемы? В Функциональном компоненте.
function App() {
let [users, setUsers] = useState([]);
let [formAction, setFormAction] = useState("search");
let [inputForm, setInputForm] = useState(<SearchInput/>);
const setNewUser = (newUser) => {
setUsers([...users, newUser]);
console.log(users);
}
const turnFormAction = (event) => {
event.preventDefault();
if (formAction === 'search') {
setFormAction("create");
setInputForm(<CreateInput users={users} setNewUser={setNewUser}/>);
}
else {
// formAction === 'create
setFormAction("search");
setInputForm(<SearchInput/>);
}
};
return (
<div className="app">
<div className="control">
<form className="control-form">
{formAction === "search"
? (
<button className="control-turn" onClick={turnFormAction}>
Add a user
</button>
)
: (
<button className="control-turn" onClick={turnFormAction}>Return to search</button>
)}
{inputForm}
</form>
<Output users={users}/>
</div>
</div>
);
}
export default App;
function CreateInput(props) {
let createInput = useRef(null);
const handleInputFocus = (event) => {
createInput.current.setAttribute("placeholder", "");
};
const handleInputBlur = (event) => {
createInput.current.setAttribute("placeholder", "Write a name of a user");
};
return (
<fieldset className="control-create">
<button className="control-create-button">Close</button>
<input
ref={createInput}
type="text"
placeholder="Write a name of a user"
onFocus={handleInputFocus}
onBlur={handleInputBlur}
/>
<button
type="button"
className="control-create-button"
onClick={() => {
props.setNewUser(createInput.current.value)
}}
>
Create
</button>
</fieldset>
);
}
export default CreateInput;
Ответы (1 шт):
Сразу при смене состояния запускается перерисовка, и до следующей строки дело не доходит никогда. Код после установки состояния дальше не выполняется. Если хотите сразу две переменных состояния менять - это надо делать одной строкой, и обе переменный хранить в одном обьекте, примерно так.
let [formAction, setFormAction] =
useState({status: "search", inputForm: <SearchInput/>});
const turnFormAction = (event) => {
event.preventDefault();
if (formAction === 'search') {
setFormAction({
status: "create"
inputForm: <CreateInput users={users} setNewUser={setNewUser}/>
});
}
else {
// formAction === 'create
setFormAction({
status: "search"
inputForm: <SearchInput/>
});
}
};
Но если проще - Вам надо по нажатию на кнопку просто менять состояния, без условного перехода и для простоты сделать его bool (false/true изначально)
let [formAction, setFormAction] = useState("true");
turnFormAction => () = {
setFormAction(!formAction)
}
А input отрисовывать в зависимости от состояния:
<form className="control-form">
{formAction
? (
<button className="control-turn" onClick={turnFormAction}>
Add a user
</button>
)
: (
<button className="control-turn" onClick={turnFormAction}>Return to search</button>
)}
{inputForm}
</form>
Ну и еще нельзя менять свойства обьекта внутри своего обьекта - для этого есть состояние. Свойства это то что передается из родительского компонента. Это так же будет вести к ошибкам в дальнейшем