reactjs 当数组属性更改时,React组件不会重新呈现

2guxujil  于 2022-11-29  发布在  React
关注(0)|答案(2)|浏览(168)

我希望App组件在每次keys更改时显示键,我通过将键作为Appprop传递来实现这一点:

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/changing-props-on-react-root-component-forked-3mv0xf?file=/src/index.tsx
为什么会这样?如何解决?
小孙试了试:setKeysState([...keys, 'a'])。这也不会重新呈现App
实时代码:https://codesandbox.io/s/changing-props-on-react-root-component-forked-3mv0xf?file=/src/index.tsx

fnatzsnv

fnatzsnv1#

所有动态数据都需要由React管理。将事件放入组件中并更新本地状态。

function App({ initialKeys }: { initialKeys: string[] }) {
  const [keys, setKeys] = React.useState(initialKeys);
  console.log(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/changing-props-on-react-root-component-forked-l869dd?file=/src/index.tsx

rkue9o1l

rkue9o1l2#

如果您使用下面的策略,它将按照您希望的方式工作。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);

相关问题