React Context with Hooks 总是 "one step behind"
React Context with Hooks is always "one step behind"
我正在为一个计算机比较网站编写代码,在为 API 调用设置过滤器时遇到了问题。添加过滤器时似乎总是 "one step behind" 。例如,我为 "orderby" 添加过滤器,然后调用 getComputers()
,它使用过滤器作为参数从我们的 api 获取 pc,但它不应用任何参数,因为过滤器仍然是空的。如果我用 "orderby" 的不同值再次执行此操作,它会将之前的值作为 api 调用的参数。我不明白为什么会这样工作,非常感谢任何帮助:)
是的,我以前研究过这个,但似乎没有什么适合我的...
这是我的代码:
搜索结果页:
import React from 'react';
import { useContext } from 'react';
import SearchContext from '../../context/search/SearchContext';
import Navbar from '../layout/Navbar';
import Computers from '../computer/Computers';
import Select from 'react-select';
const SearchResults = () => {
const searchContext = useContext(SearchContext);
const { filters, orders, getComputers, addFilter } = searchContext;
return (
<>
<Navbar activeItem='Search'></Navbar>
<div className='container my-3 text-dark'>
<div className='row'>
<div className='col-lg-9 col-md-6'>
<h1 className='display-3 mt-3'>Suche</h1>
</div>
<div className='col-lg-3 col-md-6'>
<Select
placeholder='Sortierung'
options={orders.map(order => {
return { value: order.value, label: order.trans };
})}
onChange={val => {
addFilter({ name: 'orderby', value: val.value });
getComputers();
}}
/>
</div>
</div>
<div className='my-3'>
{filters.map((filter, index) => {
var text = filter.value.toString();
return (
<span
className='badge badge-pill badge-secondary mx-1 p-2'
key={index}
>
{text.charAt(0).toUpperCase() + text.slice(1)}
</span>
);
})}
</div>
<Computers></Computers>
</div>
</>
);
};
export default SearchResults;
奇怪的是,我的页面在小药丸中正确显示了当前的 "orderby" 过滤器(见第 42 行)。但是 API 调用没有采用正确的过滤器...
我上下文的相关部分:
SearchState.js:
const [state, dispatch] = useReducer(SearchReducer, initialState);
// ACTIONS
// Add filter
const addFilter = filter => {
console.log(state.filters);
dispatch({ type: ADD_FILTER, payload: filter });
};
// Get PCs from API
const getComputers = async () => {
try {
state.loading = true;
console.log(state.filters);
let params = {};
state.filters.forEach(filter => {
// if (filter.name !== 'usecase' && filter.name !== 'type')
//only as long as usecase and type are not implemented in api yet
if (!params[filter.name]) params[filter.name] = '';
params[filter.name] = filter.value;
});
console.log(params);
const res = await axios.get(
'notgonnatellumyurlxd',
{
params
}
);
console.log(res);
dispatch({ type: GET_COMPUTERS, payload: res.data });
} catch (err) {
console.log(err);
}
};
SearchReducer.js:
export default (state, action) => {
switch (action.type) {
case ADD_FILTER:
// Used for deciding whether to update existing filter or set new
var update = false;
state.filters.forEach(filter => {
if (filter.name === action.payload.name) {
update = true;
}
});
return {
...state,
filters: !update
? [...state.filters, action.payload]
: state.filters.map(filter =>
filter.name === action.payload.name ? action.payload : filter
)
};
.
.
.
case GET_COMPUTERS:
return {
...state,
computers: action.payload,
loading: false
};
};
我现在真的很苦恼,希望能在这里找到一些帮助。非常感谢!你们这里的人很棒:)
getComputers
适用于其他 state
"instance"/ref`
您可以使用 useEffect
作为 addFilter
更改 filter
:
useEffect(() => {
getComputers();
}, [filter]);
onChange={val => addFilter({ name: 'orderby', value: val.value })}
addFilter
更改filter
... filter
更改运行效果代码(每次更改)
我正在为一个计算机比较网站编写代码,在为 API 调用设置过滤器时遇到了问题。添加过滤器时似乎总是 "one step behind" 。例如,我为 "orderby" 添加过滤器,然后调用 getComputers()
,它使用过滤器作为参数从我们的 api 获取 pc,但它不应用任何参数,因为过滤器仍然是空的。如果我用 "orderby" 的不同值再次执行此操作,它会将之前的值作为 api 调用的参数。我不明白为什么会这样工作,非常感谢任何帮助:)
是的,我以前研究过这个,但似乎没有什么适合我的...
这是我的代码:
搜索结果页:
import React from 'react';
import { useContext } from 'react';
import SearchContext from '../../context/search/SearchContext';
import Navbar from '../layout/Navbar';
import Computers from '../computer/Computers';
import Select from 'react-select';
const SearchResults = () => {
const searchContext = useContext(SearchContext);
const { filters, orders, getComputers, addFilter } = searchContext;
return (
<>
<Navbar activeItem='Search'></Navbar>
<div className='container my-3 text-dark'>
<div className='row'>
<div className='col-lg-9 col-md-6'>
<h1 className='display-3 mt-3'>Suche</h1>
</div>
<div className='col-lg-3 col-md-6'>
<Select
placeholder='Sortierung'
options={orders.map(order => {
return { value: order.value, label: order.trans };
})}
onChange={val => {
addFilter({ name: 'orderby', value: val.value });
getComputers();
}}
/>
</div>
</div>
<div className='my-3'>
{filters.map((filter, index) => {
var text = filter.value.toString();
return (
<span
className='badge badge-pill badge-secondary mx-1 p-2'
key={index}
>
{text.charAt(0).toUpperCase() + text.slice(1)}
</span>
);
})}
</div>
<Computers></Computers>
</div>
</>
);
};
export default SearchResults;
奇怪的是,我的页面在小药丸中正确显示了当前的 "orderby" 过滤器(见第 42 行)。但是 API 调用没有采用正确的过滤器...
我上下文的相关部分:
SearchState.js:
const [state, dispatch] = useReducer(SearchReducer, initialState);
// ACTIONS
// Add filter
const addFilter = filter => {
console.log(state.filters);
dispatch({ type: ADD_FILTER, payload: filter });
};
// Get PCs from API
const getComputers = async () => {
try {
state.loading = true;
console.log(state.filters);
let params = {};
state.filters.forEach(filter => {
// if (filter.name !== 'usecase' && filter.name !== 'type')
//only as long as usecase and type are not implemented in api yet
if (!params[filter.name]) params[filter.name] = '';
params[filter.name] = filter.value;
});
console.log(params);
const res = await axios.get(
'notgonnatellumyurlxd',
{
params
}
);
console.log(res);
dispatch({ type: GET_COMPUTERS, payload: res.data });
} catch (err) {
console.log(err);
}
};
SearchReducer.js:
export default (state, action) => {
switch (action.type) {
case ADD_FILTER:
// Used for deciding whether to update existing filter or set new
var update = false;
state.filters.forEach(filter => {
if (filter.name === action.payload.name) {
update = true;
}
});
return {
...state,
filters: !update
? [...state.filters, action.payload]
: state.filters.map(filter =>
filter.name === action.payload.name ? action.payload : filter
)
};
.
.
.
case GET_COMPUTERS:
return {
...state,
computers: action.payload,
loading: false
};
};
我现在真的很苦恼,希望能在这里找到一些帮助。非常感谢!你们这里的人很棒:)
getComputers
适用于其他 state
"instance"/ref`
您可以使用 useEffect
作为 addFilter
更改 filter
:
useEffect(() => {
getComputers();
}, [filter]);
onChange={val => addFilter({ name: 'orderby', value: val.value })}
addFilter
更改filter
... filter
更改运行效果代码(每次更改)