Я хочу, чтобы мой компонент App
отображал ключи при каждом изменении keys
. Я делаю это с помощью переданных ключей как prop
из App
:
import * as React from "react";
import { render } from "react-dom";
import { useState, useEffect } from "react"
let keys: string[] = [];
// This is what is supposed to happen in the real app
// document.addEventListener("keypress", (event) => {
// keys.push(event.key)
// });
setTimeout(() => {
keys.push('a');
}, 1000)
function App({ keys }: { keys: string[] }) {
let [keysState, setKeysState] = useState(keys)
useEffect(() => {
setKeysState(keys)
}, [keys])
return (
<div>
{keysState.map((key: string) => (
<li>{key}</li>
))}
</div>
);
}
const rootElement = document.getElementById("root");
render(<App keys = {keys} />, rootElement);
Однако приложение не перерисовывает и не отображает новое значение ключей:
https://codesandbox.io/s/change-props-on-react-root-component-forked-3mv0xf?file=/src/index.tsx
Почему это и как это исправить?
Примечание: я пытался: setKeysState([...keys, 'a'])
. Это тоже не перерисовывается App
.
Живой код: https://codesandbox.io/s/change-props-on-react-root-component-forked-3mv0xf?file=/src/index.tsx
@ Андрей Хорошо, я исправил это.
Все данные, которые являются динамическими, должны управляться React. Поместите ваше событие внутри компонента и обновите локальное состояние.
function App({ initialKeys }: { initialKeys: string[] }) {
const [keys, setKeys] = React.useState(initialKeys);
console.info(keys);
React.useEffect(() => {
const append = (e) => {
setKeys([...keys, e.key]);
};
document.addEventListener("keypress", append);
return () => {
document.removeEventListener("keypress", append);
};
}, [keys]);
return (
<div>
{keys.map((key: string, idx) => (
<li key = {idx}>{key}</li>
))}
</div>
);
}
https://codesandbox.io/s/change-props-on-react-root-component-forked-l869dd?file=/src/index.tsx
вы предполагаете изменить состояние в тайм-ауте, а не сразу перед инициализацией компонента
Спасибо, но есть ли способ отобразить keys
в компоненте React, не помещая в него логику keypress
? Например, обнаружение изменений в key
и повторный рендеринг компонента?
если вы используете приведенную ниже стратегию, она работает так, как вы хотите. React не может видеть изменения состояния из своих встроенных функций, поэтому он не отслеживал изменения в вашем массиве, которые выходили за рамки его состояния.
import * as React from "react";
import { render } from "react-dom";
import { useState, useEffect } from "react";
let keys: string[] = [];
function App(props: any) {
const [keys, oldKeysState] = useState(props.keys);
const [keysState, setKeysState] = useState(keys);
useEffect(() => {
setKeysState(keys);
}, [keys]);
// componentWillMount
useEffect(() => {
setTimeout(() => {
oldKeysState([...keys, "a"]);
}, 1000);
}, []);
return (
<div>
{keysState.map((key: string) => (
<li>{key}</li>
))}
<button onClick = {() => setKeysState([...keysState, "+"])}>+</button>
</div>
);
}
const rootElement = document.getElementById("root");
render(<App keys = {keys} />, rootElement);
Ваша песочница кода отличается от вашего фрагмента кода в вашем вопросе