我有一个简单的反应应用程序,其中有一个FruitsList组件用于显示列表中的水果,一个FruitForm组件用于添加水果,两者都包含在Fruits组件中。我正在使用useContext
和useReducer
管理水果的状态。我已经为它创建了一个FruitContext。我想停止FruitForm的重新渲染,因为它只使用调度功能并且每次添加新水果时重新渲染它都是无用的。请建议任何解决方案。
表单组件
const Form = () => {
const { dispatch } = useContext(FruitsContext);
const { setLoading } = useContext(LoaderContext);
let formRef = null;
const fruit = {};
const formSubmitHandler = async (event) => {
event.preventDefault();
setLoading(true);
await fetch('https://fruit-basket-74269.firebaseio.com/fruits.json', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(fruit)
});
dispatch({type: 'ADD', fruit: fruit});
// formRef.reset();
setLoading(false);
}
return (
<Card>
{console.log('[Form]')}
<form ref={ref => formRef = ref} onSubmit={formSubmitHandler} className={style.form} autoComplete="off">
<div className={style.formGroup}>
<input onChange={event => fruit.item = event.target.value} className={style.input} type="text" id="name" placeholder="Enter fruit name" />
<label className={style.label} htmlFor="name">Name</label>
</div>
<div className={style.formGroup}>
<input onChange={event => fruit.qty = event.target.value} className={style.input} type="number" min="0" id="qty" placeholder="Enter quantity" />
<label className={style.label} htmlFor="qty">Quantity</label>
</div>
<Button>Add Fruit</Button>
</form>
</Card>
)
}
export default React.memo(Form);
水果清单
const FruitList = () => {
const { fruits } = useContext(FruitsContext);
console.log('[FruitList]:', fruits);
return useMemo(() => {
return (
<div className={style.fruitList}>
<h2 className={style.heading}>Fruits</h2>
<hr />
<div className={style.list}>
<FruitCard name={'Apple'} qty={15} />
<FruitCard name={'Orange'} qty={10} />
<FruitCard name={'Grapes'} qty={20} />
</div>
</div>
);
}, []);
}
export default FruitList;
水果
const Fruits = () => {
console.log('[Fruits Parent]');
// const { loading } = useContext(LoaderContext);
return (
<div className={style.fruits}>
{/* {loading && <Loader />} */}
<Form />
<br />
<Filter />
<br />
<FruitList />
</div>
)
}
export default Fruits
FruitContext
export const FruitsContext = createContext();
const FruitsProvider = ({children}) => {
const [fruits, dispatch] = useReducer(reducer, []);
const value = ({
fruits, dispatch
});
return (
<FruitsContext.Provider value={value}>
{ children }
</FruitsContext.Provider>
);
}
export default FruitsProvider;
水果减速机
export default (state, action) => {
switch(action.type) {
case 'LOAD':
return action.fruits
case 'ADD':
console.log('[Pre-Action]', state);
const newList = [...state];
newList.push(action.fruit);
console.log('[Post-Action]', newList);
return newList;
case 'DELETE':
return state.filter(fruit => fruit.id !== action.id);
default: return state;
}
}