Я новичок в использовании контекста в реакции. У меня есть массив объектов, содержащихся в контексте, подобном этому:
allQueries: [
{
id: 0,
operator: 'AND',
field: 'current_full_path',
from: 'xyz',
to: '',
selection: '',
addDisabled: true,
},
{
id: 1,
operator: 'AND',
field: 'user',
from: 'Bob',
to: '',
selection: '',
addDisabled: true,
},
{
id: 2,
operator: 'AND',
field: 'package_type',
from: '',
to: '',
selection: 'large',
addDisabled: true,
},
{
etc...
}
],
Версия этого будет отправлена как тело запроса на сервер, который вернет набор данных на основе запроса.
Проблема, с которой я столкнулся, заключается в том, чтобы очистить вышеуказанное перед отправкой. Мне нужно удалить поле «id», поле «addDisabled» и т. Д. c. et c. и мне нужно сделать это без изменения фактического массива объектов, содержащихся в контексте, потому что его нужно использовать снова после этого.
Я пробовал заполнить локальное состояние массивом из контекста и проведение изменений там. Я также попытался установить для него пустой массив в новом контексте и внести в него изменения, однако, что бы я ни делал, исходный массив allQueries также продолжает обновляться, а это означает, что пользователи не могут вносить уточнения в свой поиск после начальный поиск был произведен.
Я в тупике - есть ли у кого-нибудь идеи?
ps - как указано выше, в настоящее время пытаюсь переместить его в другой контекст, чтобы обойти this - для более полной детализации полный код компонента приведен ниже:
Спасибо
import React, { useEffect, useContext } from 'react';
import AndQueryContext from '../../context/andQuery/andQueryContext';
import SendQueryContext from '../../context/sendQuery/sendQueryContext';
const SearchButton = () => {
const andQueryContext = useContext(AndQueryContext);
const sendQueryContext = useContext(SendQueryContext);
const { allQueries } = andQueryContext;
const { objToSend, updateObjToSend } = sendQueryContext;
useEffect(() => {
updateObjToSend(allQueries);
//eslint-disable-next-line
}, [allQueries]);
const prepareQuery = (objToSend) => {
console.clear('objToSend: ', objToSend);
const queryObj = {};
prepareAndQueries(objToSend, queryObj);
console.log('queryObj after: ', queryObj);
};
const prepareAndQueries = (objToSend, queryObj) => {
console.log('objToSend: ', objToSend);
objToSend.map((item, index) => {
delete item.id;
delete item.addDisabled;
if (
item.field === 'package_type' ||
item.field === 'document_type' ||
item.field === 'user' ||
item.field === 'status'
) {
delete item.from;
delete item.to;
}
if (
item.field === 'current_full_path' ||
item.field === 'date' ||
item.field === 'size'
) {
delete item.selection;
}
});
console.log('objToSend after filter: ', objToSend);
console.log('allQueries after filter: ', allQueries);
queryObj.initial = objToSend;
return queryObj;
};
return (
<div className='col-2'>
<button
className='btn btn-labelled btn-info btn-sm'
onClick={(e) => prepareQuery(objToSend)}
>
<span className='btn-label'>
<i className='fas fa-search'></i>
</span>
Search
</button>
</div>
);
};
export default SearchButton;
Хук контекста вводит другой файл AndQueryState. js:
import React, { useReducer } from 'react';
// import axios from 'axios';
import AndQueryContext from './andQueryContext';
import AndQueryReducer from './andQueryReducer';
import {
UPDATE_ALL_QUERIES,
UPDATE_DROPDOWN_ARRAY,
UPDATE_REMOVED_DROPDOWN,
UPDATE_USE_OR,
// SEND_QUERY,
} from '../types';
const AndQueryState = (props) => {
const initialState = {
initialQuery: {
id: 0,
operator: 'AND',
field: 'current_full_path',
from: '',
to: '',
selection: '',
addDisabled: true,
},
allQueries: [
{
id: 0,
operator: 'AND',
field: 'current_full_path',
from: '',
to: '',
selection: '',
addDisabled: true,
},
],
dropDownFieldsInitial: [
'current_full_path',
'date',
'size',
'package_type',
'document_type',
'user',
'status',
],
dropDownFields: [
'current_full_path',
'date',
'size',
'package_type',
'document_type',
'user',
'status',
],
// old ones
sendToApi: 'https://api.github.com/search/users?q=stefemil',
loading: false,
useOr: 0, // determines whether OR clauses are to be used
};
const [state, dispatch] = useReducer(AndQueryReducer, initialState);
const updateAllQueries = (allQueriesFromComp) => {
dispatch({
type: UPDATE_ALL_QUERIES,
payload: allQueriesFromComp,
});
};
const updateDropDownArray = (filteredDropDownFields) => {
dispatch({
type: UPDATE_DROPDOWN_ARRAY,
payload: filteredDropDownFields,
});
};
const updateRemovedDropDown = (dropDownOption) => {
dispatch({
type: UPDATE_REMOVED_DROPDOWN,
payload: dropDownOption, // need to do this to stop it sticking an array within an array
});
};
const updateUseOr = (updatedUseOr) => {
console.log('useOr passed from component: ', updatedUseOr);
dispatch({
type: UPDATE_USE_OR,
payload: updatedUseOr, // need to do this to stop it sticking an array within an array
});
};
return (
<AndQueryContext.Provider
value={{
initialQuery: state.initialQuery,
allQueries: state.allQueries,
dropDownFieldsInitial: state.dropDownFieldsInitial,
dropDownFields: state.dropDownFields,
dropDownRemoved: state.dropDownRemoved,
useOr: state.useOr,
loading: state.loading,
updateAllQueries,
updateDropDownArray,
updateRemovedDropDown,
updateUseOr,
}}
>
{props.children}
</AndQueryContext.Provider>
);
};
export default AndQueryState;