#reactjs #react-state-management
#reactjs #реагирование-управление состоянием
Вопрос:
Прошу прощения, если ответ очевиден. Вероятно, я пропустил шаблон для этого…
У меня есть такая архитектура (конечно, более сложная): компонент (здесь кнопка) должен вызывать функцию и устанавливать состояние одновременно.
Конечно, этот пример не работает, потому что отображаемое состояние word
не определено до speak()
вызова функции.
Каков наилучший способ сделать это?
const Speaker = () => {
const [word, setWord]= useState ("nothing")
const speak = () => {
console.log(word)
...
}
const speakDirectly = () => {
setWord("hello")
speak() // say "nothing" instead of "hello" 😞
}
const prepareWord = (wordToPrepare) => {
setWord(wordToPrepare)
}
return (
<>
<p>Thinking word : {word} </p>
<button onClick={() =>prepareWord('Goodbye')} >Prepare to say "Goodbye"</button>
<button onClick={() =>prepareWord('Goodnight')} >Prepare to say "Goodnight"</button>
----
<button onClick={() =>speak()} >Say Hello</button>
<button onClick={() =>speakDirectly('hello')} >Say Hello</button>
</>
)
}
Существует ли шаблон для разрешения этого поведения в React?
Я хочу избежать обновления моих функций подобным образом 🤢
const Speaker = () => {
const [word, setWord]= useState ("nothing")
const speak = (directWord) => {
let wordToSay = directWord || word
console.log(word)
...
}
const speakDirectly = (directWord) => {
setWord(directWord)
speak(directWord)
}
...
Комментарии:
1.
setWord()
вот асинхронный.2. Да, тогда это невозможно? Мне абсолютно необходимо иметь разделенную логику между этими компонентами?
3. Не невозможно.
4. да, это подтверждает то, что я думал… Большое вам спасибо
5. Вы можете использовать эффект, чтобы обойти вашу проблему.
Ответ №1:
Вы могли бы сделать что-то вроде этого. Укажите состояние для вашего word и вашего прямого word. Используйте эффект для вашего прямого слова, чтобы запускать speak всякий раз, когда оно обновляется, но вызывайте speak по щелчку для вашего готового слова.
const Speaker = () => {
const [preparedWord, setPreparedWord]= useState();
const [directWord, setDirectWord]= useState();
const speak = (word) => {
console.log(word)
...
}
useEffect(() => directWord amp;amp; speak(directWord), [directWord]);
return (
<>
<p>Thinking word : {preparedWord} </p>
<button onClick={() => setPreparedWord('Goodbye')} >Prepare to say "Goodbye"</button>
<button onClick={() => setPreparedWord('Goodnight')} >Prepare to say "Goodnight"</button>
----
<button onClick={() => speak(preparedWord)} >Speak</button>
<button onClick={() => setDirectWord('hello')} >Say Hello</button>
</>
)
}
Обновить
Подумав об этом секунду, если вам не нужно, чтобы прямое слово было в вашем состоянии, вы также можете избавиться от этой части и просто вызвать speak для нее, передавая ее функции.
const Speaker = () => {
const [preparedWord, setPreparedWord]= useState();
const speak = (word) => {
console.log(word)
...
}
return (
<>
<p>Thinking word : {preparedWord} </p>
<button onClick={() => setPreparedWord('Goodbye')} >Prepare to say "Goodbye"</button>
<button onClick={() => setPreparedWord('Goodnight')} >Prepare to say "Goodnight"</button>
----
<button onClick={() => speak(preparedWord)} >Speak</button>
<button onClick={() => speak('hello')} >Say Hello</button>
</>
)
}