[英]Why my component is not updated as the state from context was changed?
I'm newbie at React.我是 React 的新手。
I have App.js(grandparent), CardWrapper.js(parent which has some styles), Card.js(child), AddressSearchComponent.js and Context.js which has a common state and reducer function.我有 App.js(grandparent)、CardWrapper.js(parent)、Card.js(child)、AddressSearchComponent.js 和 Context.js,它们有一个共同的 state 和减速器 function。
I want all Cards updated newly when the address is changed.我希望在地址更改时重新更新所有卡片。
Every component referencing a context is re-rendered when a state in the context is changed as I know.据我所知,当上下文中的 state 发生更改时,引用上下文的每个组件都会重新呈现。
But in my app CardWrapper was rendered just once at first and not re-rendered a state was changed.但是在我的应用程序中 CardWrapper 最初只渲染了一次,并且没有重新渲染,state 已更改。
How can I make CardWrapper is re-rendered when list_for_cards is updated?当 list_for_cards 更新时,如何使 CardWrapper 重新呈现?
(Sorry for that my English is awful.) (对不起,我的英语很糟糕。)
App.js应用程序.js
import React from 'react';
import { ContextProvider } from './Context.js';
import AddressSearchComponentfrom './AddressSearchComponent';
import CardWrapper from './CardWrapper';
function App() {
return (
<>
<ContextProvider>
<AddressSearchComponent></AddressSearchComponent>
</ContextProvider>
<section>
<ContextProvider>
<CardWrapper></CardWrapper>
</ContextProvider>
</section>
</>
);
}
export default App;
AddressSearchComponent.js地址搜索组件.js
import { useEffect, useContext } from 'react';
import axios from 'axios';
import { StateContext, DispatchContext } from './Context.js';
async function getData(...) {
const ret = await axios.get(...);
return ret.data;
}
function AddressSearchComponent() {
const state = useContext(StateContext);
const dispatch = useContext(DispatchContext);
window.state = state; // for debug
/* useEffect changing state options when selected country is changed */
/* useEffect changing city options when selected state is changed */
/* useEffect changing list_for_cards state when city is changed */
const onChange = ({name, value}) => {
dispatch({type: 'SET', name, value});
}
return (
<div>
/* a selectbox for country options */
/* a selectbox for state options */
/* a selectbox for city options * /
</div>
)
}
export default AddressSearchComponent;
Context.js上下文.js
import React, { useReducer } from 'react';
const initialState = {
currentCountry: '',
countryList: [],
currentState: '',
stateList:[],
currentCity: '',
cityList: [],
list_for_cards: []
}
function reducer(state, action) {
switch (action.type) {
case 'SET':
return {
...state,
[action.name]: action.value
}
default:
return state;
}
}
export const StateContext = React.createContext();
export const DispatchContext = React.createContext();
export function ContextProvider({children}) {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<StateContext.Provider value={state}>
<DispatchContext.Provider value={dispatch}>
{children}
</DispatchContext.Provider>
</StateContext.Provider>
)
}
CardWrapper.js CardWrapper.js
import { useContext } from 'react';
import Card from "./Card";
import { StateContext } from './Context';
function CardWrapper() {
const { list_for_cards } = useContext(StateContext);
return (
<>
{
list_for_cards.map(item=>
<Card item={item}></Card>
)
}
</>
)
}
export default CardWrapper;
If I understand correctly, In AddressSearchComponent you only want to update state that comes from select boxes (so selected country, state and city - in your state they). If I understand correctly, In AddressSearchComponent you only want to update state that comes from select boxes (so selected country, state and city - in your state they). But you need to add these new values to the list_for_cards as well, and you have to update your list state in the reducer.
但是您还需要将这些新值添加到 list_for_cards 中,并且您必须在减速器中更新您的列表 state。
Actually, there is a minor problem with your app.js实际上,您的 app.js 有一个小问题
You are wrapping <AddressSearchComponent/> & <CardWrapper />
with <ContextProvider />
but in wrong way.您正在用
<ContextProvider />
包装<AddressSearchComponent/> & <CardWrapper />
> 但方式错误。 Both of your compoent should inside one warpper.你的两个组件都应该在一个整经机内。
It should be wrapped like the following.它应该像下面这样包装。
import React from 'react';
import { ContextProvider } from './Context';
import AddressSearchComponentfrom './AddressSearchComponent';
import CardWrapper from './CardWrapper';
function App() {
return (
<>
<ContextProvider>
<AddressSearchComponent />
<CardWrapper />
</ContextProvider>
</>
);
}
export default App;
https://reactjs.org/docs/context.html#updating-context-from-a-nested-component https://reactjs.org/docs/context.html#updating-context-from-a-nested-component
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.