简体   繁体   English

数组道具更改时反应组件不重新渲染

[英]React component not re-rendering when array prop changes

I want my App component to display keys every time keys changes.我希望我的App组件在每次keys更改时显示键。 I'm doing this by passed keys as a prop of App :我通过传递密钥作为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);

However, App isn't re-rendering and displaying keys new value:但是,App 不会重新呈现和显示键的新值:

https://codesandbox.io/s/changing-props-on-react-root-component-forked-3mv0xf?file=/src/index.tsx https://codesandbox.io/s/changing-props-on-react-root-component-forked-3mv0xf?file=/src/index.tsx

Why is this, and how to fix it?为什么会这样,如何解决?

Note: I tried: setKeysState([...keys, 'a']) .注意:我试过: setKeysState([...keys, 'a']) That doesn't re-render App either.那也不会重新呈现App

Live code: https://codesandbox.io/s/changing-props-on-react-root-component-forked-3mv0xf?file=/src/index.tsx直播代码: https://codesandbox.io/s/changing-props-on-react-root-component-forked-3mv0xf?file=/src/index.tsx

All data that is dynamic needs to be managed by React.所有动态数据都需要由 React 管理。 Put your event inside the component and update local state.将您的事件放入组件并更新本地 state。

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 https://codesandbox.io/s/changing-props-on-react-root-component-forked-l869dd?file=/src/index.tsx

if you use the below strategy it works as you want it to work.如果您使用以下策略,它会按照您希望的方式工作。 React cannot see state changes out of its built-in functions so it didn't track the change on your array which was out of its state scope React 无法从其内置函数中看到 state 更改,因此它不会跟踪您的数组中超出其 state scope 的更改

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM