Die Funktion wird mehrmals aufgerufen, wenn useEffect an die untergeordnete React-Komponente übergeben wird
P粉818561682
P粉818561682 2024-03-30 15:36:26
0
2
471

Ich habe eine Seite mit mehreren ChildComponent-Tags und möchte, dass jeder ChildComponent mitgeteilt wird, welche API sie aufrufen soll, basierend auf der ChildComponent, auf die der Benutzer geklickt hat. onClick() öffnet ein Modal.

Mir ist aufgefallen, dass beim Öffnen des Modals der API-Aufruf zweimal erfolgt. Wenn ich das Modal schließe, wird der API-Aufruf erneut durchgeführt.

Was ich aus diesem Beitrag gelernt habe, ist, dass sich React korrekt verhält – indem es Funktionen in React-Funktionskomponenten mehrmals aufruft

Gibt es eine andere Möglichkeit, dies so zu strukturieren, dass jeweils nur ein Axios-API-Aufruf erfolgt?

const [posts, setPosts] = useState([]);

export default function ParentComponent() {
    const fetchPosts = useCallback(async () => {
        try {
            const result = await axios(`https://jsonplaceholder.typicode.com/posts`);
            setPosts(result.data.data);
        } catch (error) {
            console.log(error);
        }
    }, []);
}
<ChildComponent
      fetchPosts={fetchPosts}
      onClick={handleOnclick}
/>
const ChildComponent = ({ fetchPosts }) => {
    useEffect(
       () => props.fetchPosts, 
       [props.fetchPosts]
    );
}

export default memo(ChildComponent);

P粉818561682
P粉818561682

Antworte allen(2)
P粉198670603

如果您使用的是 React 18,则反应性中会出现此错误,请检查此帖子 https://taig.medium.com/prevent-react-from-triggering-useeffect-twice-307a475714d7

P粉005134685

如果我很好地理解您的问题和任务,我会尝试编写我的解决方案。

由于您在父组件上有模态控制状态,每次更改时都会触发您的父组件重新渲染,并且您的子组件也会重新渲染,并且由于函数是 JS 中的对象,因此您的 fetch 函数每次都会有不同的链接重新渲染并且您在 ChildComponent 中的 useEffect 会认为您的函数已更改。

所以,我认为最好的解决方案是为您的子组件添加备忘录,例如 export default memo(ChildComponent)您可以从“react”导入备忘录)。之后,您应该使用 useCallback 包装 fetchPosts 和 handleOnclick。你会得到类似的东西 const fetchPosts = useCallback(() => doSomething(), [])

希望有帮助。

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage