Я новичок в React hooks / Context API. Я прочитал документацию React Hook / Context, и у меня все еще возникают проблемы со следующим:
- Мои попытки обновить глобальное состояние несколькими компонентами-потребителями в настоящее время вызывают частую перезапись состояния контекста из-за перерисовки (например, состояние активности или деталей иногда равно нулю / не определено). Вероятно, поэтому ...
- ... Я получаю 400 (неправильный запрос) и / или 500 (сервер) ошибок при случайном обновлении страницы (~ 30% времени загружается контент, как ожидалось,Выдается ~ 70% ошибок. Я полагаю, что это происходит, потому что у нас есть различные состояния контекста, которые вызываются асинхронно).
- Я не уверен, как реализовать Отмена Axios, учитывая, что наши
useEffect
перехватчики вызываютфункции отправки (например, getActivities()
) в разные файлы. Примеры, которые я видел, включают выборку данных внутри компонента (а не в контексте).
Я специально ищу помощь для # 1. Мне бы хотелось получить руководство о том, как точно извлекать данные и сохранять их в контексте как глобальное состояние, а затем предоставлять этот контекст дочерним компонентам, позволяя им использовать / обновлять состояние контекста без ненужной перерисовки.
Пыталсяпредоставьте только соответствующие фрагменты кода ниже:
ActivityState.js - должен извлекать данные активности
...
const ActivityState = props => {
const initialState = {
activities: [],
isLoading: false,
isError: false
};
const HEADERS = {
'Content-Type': 'application/json',
'user_id': 1
}
const [state, dispatch] = useReducer(ActivityReducer, initialState);
const userContext = useContext(UserContext);
const getActivities = async () => {
const { loggedIn } = contactContext;
let didCancel = false; // attempts to start implementing axios cancellation
try {
const res = await axios.get(url);
dispatch({ type: GET_ACTIVITIES, payload: res.data.data.activities });
} catch (err) {
if (!didCancel) {
dispatch({ type: 'FETCH_FAILURE' });
}
}
}
const updateActivity = (path, data) => { //update context state
dispatch({ type: UPDATE_ACTIVITY, payload: { path: path, data: data } });
};
const saveActivity = () => { //send new activity data to the backend
const postData = {
actions: [{"293939": []}],
activities: state.activities
};
try {
const res = axios.post(url,{ data: postData }, { headers: HEADERS });
} catch (err) {
console.log(err);
}
}
return (
<ActivityContext.Provider
value={{
activities: state.activities,
data: state.data,
backup_data: state.backup_data,
getActivities,
updateActivity,
saveActivity,
}}
>
{props.children}
</ActivityContext.Provider>
);
};
export default ActivityState;
ActivityReducer.js - переключать операторы, которые будут отправленыby ActivityState.js
...
export default (state, action) => {
switch (action.type) {
case GET_ACTIVITIES:
return {
...state,
activities: action.payload,
isLoading: true
};
case FETCH_FAILURE:
return {
...state,
isLoading: false,
isError: true
};
case UPDATE_ACTIVITY:
const { payload: { path }, payload } = action;
const data = state;
if (!data.activities)
return { data };
const index = data.activities.findIndex(e => e.socium_tracking_number == path.id);
if(index === -1)
return { data };
_.set(data, `activities[${index}].${path.field}`, payload.data);
return {
data,
};
...
DetailsState.js - функции отправки для получения сведений
const DetailsState = props => {
const initialState = {
details: null,
};
const [state, dispatch] = useReducer(DetailsReducer, initialState);
const getDetails = async () => {
try {
const res = await axios.get(url);
dispatch({ type: GET_DETAILS, payload: res.data.data[0].details});
}catch(err) {
console.log(err)
}
};
return (
<DetailsContext.Provider
value={{ details: state.details, getDetails }}
>
{ props.children }
</DetailsContext.Provider>
);
}
export default SchemaState;
DetailsReducer.js - переключательоператор
export default (state, action) => {
switch (action.type) {
case GET_DETAILS:
return {
...state,
details: action.payload,
};
default:
return state;
}
};
ActivityTable.js - компонент, который потребляет активность Информация
...
const ActivityTable = ({ activity }) => {
const activityContext = useContext(ActivityContext);
const { activities, filtered, getActivities } = activityContext;
const [order, setOrder] = React.useState('asc');
const [orderBy, setOrderBy] = React.useState(activities.wait_time);
// Get activity data on mount
useEffect(() => {
async function fetchData() {
await getActivities()
}
fetchData();
}, []);
...
CreateActivity.js - компонент, который потребляет деятельностьи Подробные данные
...
const CreateActivity = props => {
const activityContext = useContext(ActivityContext);
const { activities, filtered, getActivities, addActivity } = activityContext;
const detailsContext = useContext(DetailsContext);
const { details, getDetails } = detailsContext;
// Get activity and details data on mount
useEffect(() => {
async function fetchData() {
await getActivities();
await getSchema();
}
fetchData();
}, []);
...
Я действительно пытался разобраться в этих проблемах, прежде чем обратиться к сообществу SO, чтобы мои вопросы были более четкими. Но это то, что у меня есть. Рад предоставить любую информацию, которую я пропустил, или уточнить путаницу. Спасибо за ваше время