Reactjs 使用Redux存储数据填充材质UI下拉列表
我试图让我的Redux存储字段自动填充我导入的方法。为了完成这件事,我是否采取了正确的方法?是否需要为每个字段创建映射选项 我在每个下拉列表中插入了一个PopulateDropdown列表和每个下拉列表中的字段,但我需要根据id和文本对它们进行拆分 我是否正确访问下面的redux商店?我使用constfields=useSelector(state=>state.fields)在我的函数组件上声明了数组 更新 我将方法插入到下拉列表中,但是我认为我没有正确访问数据,这导致了问题。字段数组已被分解为每个下拉列表的六个不同字段,并为每个字段创建了不同的映射选项 我需要做什么才能将数据输入到方法中?我看到的示例在组件上声明了静态数组,而不是使用Redux存储Reactjs 使用Redux存储数据填充材质UI下拉列表,reactjs,redux,react-redux,material-ui,Reactjs,Redux,React Redux,Material Ui,我试图让我的Redux存储字段自动填充我导入的方法。为了完成这件事,我是否采取了正确的方法?是否需要为每个字段创建映射选项 我在每个下拉列表中插入了一个PopulateDropdown列表和每个下拉列表中的字段,但我需要根据id和文本对它们进行拆分 我是否正确访问下面的redux商店?我使用constfields=useSelector(state=>state.fields)在我的函数组件上声明了数组 更新 我将方法插入到下拉列表中,但是我认为我没有正确访问数据,这导致了问题。字段数组已被分解
const fields = useSelector(state => state.fields);
// can destructure individual fields
const { diveSchoolList, currentList, regionList, diveTypeList, visibilityList, diveSpotList } = fields;
已导入的PopulatedDropDown方法
export const PopulateDropdown = ({ dataList = [], mappingOptions, name, label }) => {
const { title, value } = mappingOptions;
return (
<FormControl style={{ width: 200 }} >
<InputLabel id={label}>{label}</InputLabel>
<Select labelId={label} name={name} >
{dataList.map((item) => (
<MenuItem value={item[value]}>{item[title]}</MenuItem>
))}
</Select>
</FormControl>
);
};
export const PopulateDropdown=({dataList=[],mappingOptions,name,label})=>{
const{title,value}=mappingOptions;
返回(
{label}
{dataList.map((项)=>(
{项目[标题]}
))}
);
};
导入的下拉菜单
<PopulateDropdown
dataList={diveType}
mappingOptions={mappingOptions}
name="fieldName"
label="Select dive type"
value={dive.typeID}
onChange={handleChange}/>
更新
我已经更新了action、reducer和populateFields方法,但是我仍然无法将redux数据映射到我的两个属性字段。在Redux树中,字段应位于fields.data.FieldList下,因为在我控制台记录它们时,这些字段会打印出来
我应该以什么方式将它们填充到标题属性等中?它现在看起来像是在填充,但是一个大的框掉了下来,我在里面看不到任何值
// select user object from redux
const user = useSelector(state => state.user);
// get the object with all the fields
const fields = useSelector(state => state.fields);
// can destructure individual fields
const { diveSchoolList = [],
currentList = [],
regionList = [],
diveTypeList = [],
visibilityList = [],
diveSpotList = [],
marineTypeList = [],
articleTypeList = []
} = fields;
.........
<PopulateDropdown
dataList={fields.data.diveTypeList} // the options array
titleProperty={fields.data.diveTypeList.diveTypeID} // option label property
valueProperty={fields.data.diveTypeList.diveType} // option value property
label="Dive Type Name" // label above the select
placeholder="Select dive type" // text show when empty
value={dive.typeID} // get value from state
onChange={handleChange(setDive.typeID)} // update state on change
/>
//从redux中选择用户对象
const user=useSelector(state=>state.user);
//获取包含所有字段的对象
const fields=useSelector(state=>state.fields);
//可以分解单个字段
常量{DELPHOOLLIST=[],
currentList=[],
regionList=[],
diveTypeList=[],
可视性列表=[],
列表=[],
marineTypeList=[],
articleTypeList=[]
}=字段;
.........
您的PopulateDropdown
组件看起来是正确的,只是我们需要它使用我们作为道具传递的值和onChange
我个人的偏好是使用单独的属性valueProperty
和titleProperty
,而不是传递单个mappingOptions
。这样,您就不需要为每个下拉列表创建对象,只需在JSX中设置这两个属性。如果对数据进行规范化,使每个列表的元素具有相同的属性id
和label
,则可以完全删除此部分
<PopulateDropdown
dataList={diveTypeList} // the options array
titleProperty={"diveTypeId"} // option label property
valueProperty={"diveType"} // option value property
label="Dive Type Name" // label above the select
placeholder="Select dive type" // text show when empty
value={dive.typeID} // get value from state
onChange={handleChange("typeId")} // update state on change
/>
因此,在组件中,我们现在只需要调用一个操作,而不是在字段中循环
useEffect(() => {
dispatch(requireFieldData());
}, []);
您需要使用redux toolkit中的useSelector
,或react redux中的connect
函数将redux数据注入组件。你做得对吗?我建议你使用redux钩子来完成这项工作。如前所述,使用useSelector获取数据,使用useDispatch调度操作。你确定你做得对吗?这个答案会有帮助的:嘿,Jimbo,几周前建立了redux商店。现在看起来怎么样?如果您可以共享Github repo或CodeSandbox,它将帮助我更好地理解数据结构。我绝对认为我们可以创建一个通用组件,它将适用于所有6个列表,只需一些配置道具。看起来您所拥有的大部分都是正确的!我认为您实际上不需要将name
属性传递给select。另外,我不需要创建mappingOptions
对象,而是让PopulateDropdown
组件获取两个单独的属性valueProperty
和titleProperty
。我可以给你写一个答案,但没有上一个那么深入,因为你已经掌握了窍门!我看到你在一个API调用中获取所有字段数据,这很好。如果下拉列表看起来是填充的,但是我实际上无法读取值,因为它只是一个大的白色框,这个错误听起来与什么有关?听起来好像每个选项都有一个MenuItem
,但是我们没有提取正确的标签(这将是MenuItem
上的子项
属性)。这部分:{item[titleProperty]}
在这种情况下,我应该以什么方式填充它们?看起来它可能会用valueProp={fields.data.diveTypeList.diveType)之类的东西填充它们,但是当页面重新呈现为“fields.data未定义”并且我的存储没有填充时,我会出错。我想我可以只输入dataList名称,因为它在顶部是结构化的,然后是特定的行名称。
export const requireFieldData = createAsyncThunk(
"fields/requireData", // action name
// don't need any argument because we are now fetching all fields
async () => {
const response = await diveLogFields();
return response.data;
},
// only fetch when needed: https://redux-toolkit.js.org/api/createAsyncThunk#canceling-before-execution
{
// _ denotes variables that aren't used - the first argument is the args of the action creator
condition: (_, { getState }) => {
const { fields } = getState(); // returns redux state
// check if there is already data by looking at the didLoadData property
if (fields.didLoadData) {
// return false to cancel execution
return false;
}
}
}
);
const fieldsSlice = createSlice({
name: "fields",
initialState: {
currentList: [],
regionList: [],
diveTypeList: [],
visibilityList: [],
diveSpotList: [],
diveSchoolList: [],
marineTypeList: [],
articleTypeList: [],
didLoadData: false,
},
reducers: {},
extraReducers: {
// picks up the pending action from the thunk
[requireFieldData.pending.type]: (state) => {
// set didLoadData to prevent unnecessary re-fetching
state.didLoadData = true;
},
// picks up the success action from the thunk
[requireFieldData.fulfilled.type]: (state, action) => {
// want to replace all lists, there are multiple ways to do this
// I am returning a new state which overrides any properties
return {
...state,
...action.payload
}
}
}
});
useEffect(() => {
dispatch(requireFieldData());
}, []);