#typescript #react-native #react-hooks #use-state #react-native-sectionlist
Вопрос:
Ниже приведен мой универсальный компонент React. Я попытался упростить его, но он все еще не слишком короткий. Приношу свои извинения за это. Мое намерение состоит в том, чтобы создать редактируемое меню с атрибутами и их значениями, которые будут переданы этому компоненту из родительского компонента. staticData
были бы поля/ скелет моего представления, и dynamicData
(предположим) происходит из запроса. Я передаю dynamicData
переменную состояния в состояние newFormData
, а затем отображаю ее в SectionList
renderItem
. Я хочу обновить поля ввода, если пользователь нажмет на cancel
кнопку . Для этого я использую cancelUpdate
функцию, которая сбрасывает состояние newFormData
, в dynamicData
которое никогда не изменялось. Однако это не обновляет список разделов. Я все еще вижу отредактированные данные. Как я могу сбросить newFormData
и повторно отобразить экран. Я читал об useReducer
этом, но также читал, что это не очень хорошая практика.
редактируемый-menu.component.tsx (Несколько упрощенный)
export const EditableMenuComponent = ({
staticData,
dynamicData,
fetchOrUpdateCourierProfile,
}: {
staticData: any;
dynamicData: any;
fetchOrUpdateCourierProfile: any;
}) => {
let storedData = {};
const handleFieldChange = (value: any, attribute: string) => {
storedData[attribute] = value;
setNewFormData(storedData);
};
const [initialFormData, setInitialFormData] = useState<any>();
const [newFormData, setNewFormData] = useState<any>();
const [editable, setEditable] = React.useState<boolean>(false);
const saveProfile = () => {
setEditable(false);
fetchOrUpdateCourierProfile(MutationAction.UPDATE);
};
const cancelUpdate = () => {
console.log('cancel');
setEditable(false);
setNewFormData(dynamicData);
};
React.useEffect(() => {
setNewFormData(dynamicData);
setInitialFormData(dynamicData);
});
const renderItem = ({
item,
}: {
item: { id: string; title: string };
}) => (
<Layout level="1" style={[themedStyles.layoutContainer]}>
<Text appearance="hint" category="s1">
{item.title}
</Text>
<Input
defaultValue={newFormData ? newFormData[item.id] : ''}
// value={newFormData ? newFormData[item.id] : ''}
onChangeText={(text) => handleFieldChange(text, item.id)}
appearance="default"
disabled={!editable}
textStyle={{ color: 'black' }}
></Input>
</Layout>
);
const FlatListItemSeparator = () => {
return (
//Item Separator
<View style={themedStyles.listItemSeparatorStyle} />
);
};
return (
<SafeAreaView style={themedStyles.container}>
<ScrollView>
{editable ? (
<Header
backgroundColor="#fff"
leftComponent={
<Text
style={{ color: 'red' }}
onPress={() => {
console.log('setEdit false 1');
cancelUpdate();
}}
>
Cancel
</Text>
}
rightComponent={
<Text
style={{ color: 'blue' }}
onPress={() => {
console.log('setEdit false 2');
saveProfile();
}}
>
Save
</Text>
}
/>
) : (
<Header
backgroundColor="#fff"
rightComponent={
<Text
style={{ color: 'blue' }}
onPress={() => {
console.log('setEdit true');
setEditable(true);
}}
>
Edit
</Text>
}
/>
)}
<SectionList
ItemSeparatorComponent={FlatListItemSeparator}
sections={staticData}
renderItem={renderItem}
extraData={editable}
renderSectionHeader={({ section: { title } }) => (
<Text style={themedStyles.sectionHeaderStyle}>
{title}
</Text>
)}
keyExtractor={(item) => item.id}
/>
</ScrollView>
</SafeAreaView>
);
};