React native 已调度操作并更新状态,但未呈现UI组件
谁能在我的问题上提供支持:派遣行动确实会如预期的那样改变状态。但从中分派问题的组件不会重新呈现。当我简单地保存组件时,它当然会重新呈现并显示所需的对象 这是我的文件: actions.jsReact native 已调度操作并更新状态,但未呈现UI组件,react-native,react-redux,action,render,dispatch,React Native,React Redux,Action,Render,Dispatch,谁能在我的问题上提供支持:派遣行动确实会如预期的那样改变状态。但从中分派问题的组件不会重新呈现。当我简单地保存组件时,它当然会重新呈现并显示所需的对象 这是我的文件: actions.js export const TOGGLE_PRODUCT = "TOGGLE_PRODUCT"; export const INCREMENT = "INCREMENT"; //ACTION CREATER FUNCTIONS export const togglePr
export const TOGGLE_PRODUCT = "TOGGLE_PRODUCT";
export const INCREMENT = "INCREMENT";
//ACTION CREATER FUNCTIONS
export const toggleProduct = (id) => {
return {
type: TOGGLE_PRODUCT,
productId: id,
};
};
import { PRODUCTLIST } from "../../data/dummydata";
import { TOGGLE_PRODUCT } from "../actions/products";
const initialState = {
allProducts: PRODUCTLIST,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_PRODUCT:
const Products = state.allProducts;
const toggledProduct = Products.find((el) => el.id === action.productId);
if (toggledProduct.status === false) {
toggledProduct.status = true;
} else {
toggledProduct.status = false;
}
console.log("Neue Products: ", Products);
return {
allProducts: Products,
};
default:
return state;
}
};
export default productReducer;
import { useSelector, useDispatch } from "react-redux";
import React, { useEffect, useCallback } from "react";
import { Text, View, Button, FlatList, StyleSheet } from "react-native";
import Product from "../components/Product";
import { toggleProduct } from "../store/actions/products";
import { increment } from "../store/actions/products";
const ShoppingListScreen = (props) => {
const dispatch = useDispatch();
const toggleProductHandler = useCallback(
// useCallback verhindert infinite loop
(id) => {
dispatch(toggleProduct(id));
},
[]
);
const Products = useSelector((state) => state.product.allProducts);
return (
<View style={styles.screen}>
<FlatList
data={Products}
renderItem={({ item }) => (
<View
style={
item.status === true ? styles.elementselected : styles.element
}
>
<Product
style={styles.text}
id={item.id}
product={item.product}
department={item.department}
status={item.status}
onClick={() => toggleProductHandler(item.id)}
/>
</View>
)}
/>
<View style={styles.button}>
<Button
title="FERTIG"
onPress={() => {
props.navigation.goBack();
}}
/>
{/* <Button
title='Stand "cartRewe" '
onPress={() => {
props.testFunction1();
}}
/>
<Button
title='Stand "planRewe" '
onPress={() => {
props.testFunction2();
}}
/> */}
</View>
</View>
);
};
const styles = StyleSheet.create({
screen: {
backgroundColor: "#fafafa",
flex: 1,
justifyContent: "flex-start",
},
element: {
backgroundColor: "#ddd",
borderWidth: 2,
borderColor: "#bbb",
borderRadius: 20,
marginVertical: 5,
marginHorizontal: 25,
},
elementselected: {
backgroundColor: "#a0ffa0",
borderWidth: 3,
borderColor: "#64ff64",
borderRadius: 20,
marginVertical: 5,
marginHorizontal: 25,
},
text: {
color: "#333",
// fontSize: 22,
// marginHorizontal: 10
},
button: {
marginVertical: 24,
},
});
export default ShoppingListScreen;
import { PRODUCTLIST } from "../../data/dummydata";
import { TOGGLE_PRODUCT } from "../actions/products";
const initialState = {
allProducts: PRODUCTLIST,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_PRODUCT:
const newProducts = state.allProducts;
const toggledProduct = newProducts.findIndex(
(el, idx) => el.id === action.productId
);
if (newProducts[toggledProduct].status === false) {
newProducts[toggledProduct].status = true;
} else {
newProducts[toggledProduct].status = false;
}
return {
...state,
newProducts,
};
default:
return state;
}
};
export default productReducer;
reducer.js
export const TOGGLE_PRODUCT = "TOGGLE_PRODUCT";
export const INCREMENT = "INCREMENT";
//ACTION CREATER FUNCTIONS
export const toggleProduct = (id) => {
return {
type: TOGGLE_PRODUCT,
productId: id,
};
};
import { PRODUCTLIST } from "../../data/dummydata";
import { TOGGLE_PRODUCT } from "../actions/products";
const initialState = {
allProducts: PRODUCTLIST,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_PRODUCT:
const Products = state.allProducts;
const toggledProduct = Products.find((el) => el.id === action.productId);
if (toggledProduct.status === false) {
toggledProduct.status = true;
} else {
toggledProduct.status = false;
}
console.log("Neue Products: ", Products);
return {
allProducts: Products,
};
default:
return state;
}
};
export default productReducer;
import { useSelector, useDispatch } from "react-redux";
import React, { useEffect, useCallback } from "react";
import { Text, View, Button, FlatList, StyleSheet } from "react-native";
import Product from "../components/Product";
import { toggleProduct } from "../store/actions/products";
import { increment } from "../store/actions/products";
const ShoppingListScreen = (props) => {
const dispatch = useDispatch();
const toggleProductHandler = useCallback(
// useCallback verhindert infinite loop
(id) => {
dispatch(toggleProduct(id));
},
[]
);
const Products = useSelector((state) => state.product.allProducts);
return (
<View style={styles.screen}>
<FlatList
data={Products}
renderItem={({ item }) => (
<View
style={
item.status === true ? styles.elementselected : styles.element
}
>
<Product
style={styles.text}
id={item.id}
product={item.product}
department={item.department}
status={item.status}
onClick={() => toggleProductHandler(item.id)}
/>
</View>
)}
/>
<View style={styles.button}>
<Button
title="FERTIG"
onPress={() => {
props.navigation.goBack();
}}
/>
{/* <Button
title='Stand "cartRewe" '
onPress={() => {
props.testFunction1();
}}
/>
<Button
title='Stand "planRewe" '
onPress={() => {
props.testFunction2();
}}
/> */}
</View>
</View>
);
};
const styles = StyleSheet.create({
screen: {
backgroundColor: "#fafafa",
flex: 1,
justifyContent: "flex-start",
},
element: {
backgroundColor: "#ddd",
borderWidth: 2,
borderColor: "#bbb",
borderRadius: 20,
marginVertical: 5,
marginHorizontal: 25,
},
elementselected: {
backgroundColor: "#a0ffa0",
borderWidth: 3,
borderColor: "#64ff64",
borderRadius: 20,
marginVertical: 5,
marginHorizontal: 25,
},
text: {
color: "#333",
// fontSize: 22,
// marginHorizontal: 10
},
button: {
marginVertical: 24,
},
});
export default ShoppingListScreen;
import { PRODUCTLIST } from "../../data/dummydata";
import { TOGGLE_PRODUCT } from "../actions/products";
const initialState = {
allProducts: PRODUCTLIST,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_PRODUCT:
const newProducts = state.allProducts;
const toggledProduct = newProducts.findIndex(
(el, idx) => el.id === action.productId
);
if (newProducts[toggledProduct].status === false) {
newProducts[toggledProduct].status = true;
} else {
newProducts[toggledProduct].status = false;
}
return {
...state,
newProducts,
};
default:
return state;
}
};
export default productReducer;
component.js
export const TOGGLE_PRODUCT = "TOGGLE_PRODUCT";
export const INCREMENT = "INCREMENT";
//ACTION CREATER FUNCTIONS
export const toggleProduct = (id) => {
return {
type: TOGGLE_PRODUCT,
productId: id,
};
};
import { PRODUCTLIST } from "../../data/dummydata";
import { TOGGLE_PRODUCT } from "../actions/products";
const initialState = {
allProducts: PRODUCTLIST,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_PRODUCT:
const Products = state.allProducts;
const toggledProduct = Products.find((el) => el.id === action.productId);
if (toggledProduct.status === false) {
toggledProduct.status = true;
} else {
toggledProduct.status = false;
}
console.log("Neue Products: ", Products);
return {
allProducts: Products,
};
default:
return state;
}
};
export default productReducer;
import { useSelector, useDispatch } from "react-redux";
import React, { useEffect, useCallback } from "react";
import { Text, View, Button, FlatList, StyleSheet } from "react-native";
import Product from "../components/Product";
import { toggleProduct } from "../store/actions/products";
import { increment } from "../store/actions/products";
const ShoppingListScreen = (props) => {
const dispatch = useDispatch();
const toggleProductHandler = useCallback(
// useCallback verhindert infinite loop
(id) => {
dispatch(toggleProduct(id));
},
[]
);
const Products = useSelector((state) => state.product.allProducts);
return (
<View style={styles.screen}>
<FlatList
data={Products}
renderItem={({ item }) => (
<View
style={
item.status === true ? styles.elementselected : styles.element
}
>
<Product
style={styles.text}
id={item.id}
product={item.product}
department={item.department}
status={item.status}
onClick={() => toggleProductHandler(item.id)}
/>
</View>
)}
/>
<View style={styles.button}>
<Button
title="FERTIG"
onPress={() => {
props.navigation.goBack();
}}
/>
{/* <Button
title='Stand "cartRewe" '
onPress={() => {
props.testFunction1();
}}
/>
<Button
title='Stand "planRewe" '
onPress={() => {
props.testFunction2();
}}
/> */}
</View>
</View>
);
};
const styles = StyleSheet.create({
screen: {
backgroundColor: "#fafafa",
flex: 1,
justifyContent: "flex-start",
},
element: {
backgroundColor: "#ddd",
borderWidth: 2,
borderColor: "#bbb",
borderRadius: 20,
marginVertical: 5,
marginHorizontal: 25,
},
elementselected: {
backgroundColor: "#a0ffa0",
borderWidth: 3,
borderColor: "#64ff64",
borderRadius: 20,
marginVertical: 5,
marginHorizontal: 25,
},
text: {
color: "#333",
// fontSize: 22,
// marginHorizontal: 10
},
button: {
marginVertical: 24,
},
});
export default ShoppingListScreen;
import { PRODUCTLIST } from "../../data/dummydata";
import { TOGGLE_PRODUCT } from "../actions/products";
const initialState = {
allProducts: PRODUCTLIST,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_PRODUCT:
const newProducts = state.allProducts;
const toggledProduct = newProducts.findIndex(
(el, idx) => el.id === action.productId
);
if (newProducts[toggledProduct].status === false) {
newProducts[toggledProduct].status = true;
} else {
newProducts[toggledProduct].status = false;
}
return {
...state,
newProducts,
};
default:
return state;
}
};
export default productReducer;
从“react-redux”导入{useSelector,useDispatch};
从“React”导入React,{useffect,useCallback};
从“react native”导入{文本、视图、按钮、平面列表、样式表};
从“./部件/产品”进口产品;
从“./store/actions/products”导入{toggleProduct};
从“./store/actions/products”导入{increment};
const ShoppingListScreen=(道具)=>{
const dispatch=usedpatch();
const toggleProductHandler=useCallback(
//UseT无限循环
(id)=>{
调度(切换产品(id));
},
[]
);
const Products=useSelector((state)=>state.product.allProducts);
返回(
(
toggleProductHandler(item.id)}
/>
)}
/>
{
props.navigation.goBack();
}}
/>
{/* {
props.testFunction1();
}}
/>
{
props.testFunction2();
}}
/> */}
);
};
const styles=StyleSheet.create({
屏幕:{
背景色:“fafafa”,
弹性:1,
justifyContent:“灵活启动”,
},
要素:{
背景颜色:“ddd”,
边界宽度:2,
边框颜色:“bbb”,
边界半径:20,
第五名:,
marginHorizontal:25,
},
所选元素:{
背景色:“a0ffa0”,
边框宽度:3,
边框颜色:“64ff64”,
边界半径:20,
第五名:,
marginHorizontal:25,
},
正文:{
颜色:“333”,
//尺寸:22,
//marginHorizontal:10
},
按钮:{
澳门时间:24,,
},
});
导出默认购物列表屏幕;
这些行是问题所在:
const Products=state.allProducts;
const-toggledProduct=Products.find((el)=>el.id==action.productId);
if(toggledProduct.status===false){
toggledProduct.status=true;
}否则{
toggledProduct.status=false;
}
返回{
所有产品:产品,
};
这改变了现有的状态,并且
要解决此问题,您需要更新副本并返回这些副本
话虽如此,更好的选择是,这是我们推荐的编写Redux逻辑的方法。它允许您编写“变异”逻辑,将其转换为安全和正确的不可变更新
以下是Redux Toolkit的createSlice
API的外观:
const productsSlice=createSlice({
名称:'产品',
initialState:{allProducts:[]},
减速器:{
productToggled(状态、操作){
const-toggledProduct=state.allProducts.find(e=>e.id==action.payload);
//这种“变异”语法只适用于Redux工具包的CreateSicle/createReducer!
toggledProduct.status=!toggledProduct.status;
}
}
})
不改变state对象完全有道理。因为我现在确实想为这个问题实现一个更进一步的包,所以我按照建议修改了我的源代码。由于任何原因,我的组件在没有手动保险箱的情况下仍然无法重新启动。这个代码怎么样,还有什么问题吗
reducer.js
export const TOGGLE_PRODUCT = "TOGGLE_PRODUCT";
export const INCREMENT = "INCREMENT";
//ACTION CREATER FUNCTIONS
export const toggleProduct = (id) => {
return {
type: TOGGLE_PRODUCT,
productId: id,
};
};
import { PRODUCTLIST } from "../../data/dummydata";
import { TOGGLE_PRODUCT } from "../actions/products";
const initialState = {
allProducts: PRODUCTLIST,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_PRODUCT:
const Products = state.allProducts;
const toggledProduct = Products.find((el) => el.id === action.productId);
if (toggledProduct.status === false) {
toggledProduct.status = true;
} else {
toggledProduct.status = false;
}
console.log("Neue Products: ", Products);
return {
allProducts: Products,
};
default:
return state;
}
};
export default productReducer;
import { useSelector, useDispatch } from "react-redux";
import React, { useEffect, useCallback } from "react";
import { Text, View, Button, FlatList, StyleSheet } from "react-native";
import Product from "../components/Product";
import { toggleProduct } from "../store/actions/products";
import { increment } from "../store/actions/products";
const ShoppingListScreen = (props) => {
const dispatch = useDispatch();
const toggleProductHandler = useCallback(
// useCallback verhindert infinite loop
(id) => {
dispatch(toggleProduct(id));
},
[]
);
const Products = useSelector((state) => state.product.allProducts);
return (
<View style={styles.screen}>
<FlatList
data={Products}
renderItem={({ item }) => (
<View
style={
item.status === true ? styles.elementselected : styles.element
}
>
<Product
style={styles.text}
id={item.id}
product={item.product}
department={item.department}
status={item.status}
onClick={() => toggleProductHandler(item.id)}
/>
</View>
)}
/>
<View style={styles.button}>
<Button
title="FERTIG"
onPress={() => {
props.navigation.goBack();
}}
/>
{/* <Button
title='Stand "cartRewe" '
onPress={() => {
props.testFunction1();
}}
/>
<Button
title='Stand "planRewe" '
onPress={() => {
props.testFunction2();
}}
/> */}
</View>
</View>
);
};
const styles = StyleSheet.create({
screen: {
backgroundColor: "#fafafa",
flex: 1,
justifyContent: "flex-start",
},
element: {
backgroundColor: "#ddd",
borderWidth: 2,
borderColor: "#bbb",
borderRadius: 20,
marginVertical: 5,
marginHorizontal: 25,
},
elementselected: {
backgroundColor: "#a0ffa0",
borderWidth: 3,
borderColor: "#64ff64",
borderRadius: 20,
marginVertical: 5,
marginHorizontal: 25,
},
text: {
color: "#333",
// fontSize: 22,
// marginHorizontal: 10
},
button: {
marginVertical: 24,
},
});
export default ShoppingListScreen;
import { PRODUCTLIST } from "../../data/dummydata";
import { TOGGLE_PRODUCT } from "../actions/products";
const initialState = {
allProducts: PRODUCTLIST,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_PRODUCT:
const newProducts = state.allProducts;
const toggledProduct = newProducts.findIndex(
(el, idx) => el.id === action.productId
);
if (newProducts[toggledProduct].status === false) {
newProducts[toggledProduct].status = true;
} else {
newProducts[toggledProduct].status = false;
}
return {
...state,
newProducts,
};
default:
return state;
}
};
export default productReducer;