在问题末尾查看更新
也请参阅第二次更新
我有一个包含两个项目的简单对象(尽管可能会增长到更多):
const initialValues = {
noLabels: false,
useFormik: false,
}
我现在想使用React Hooks来切换该对象中给定项目的值。这将起作用的方式是,我将检查是否设置了道具。如果设置了道具,那么我想将值切换为true。如果未设置,则将其保留为false。
例如:
<Form noLabels>
...
</Form>
这会将noLabels
设置为true
。
我正试图弄清楚如何编写一个简单的函数来完成此操作,而无需写else if
语句。
所以,我想要一个看起来像这样的简单函数:
const toggleValues = setValues(props.value = !props.value)
当然,prop.value
不起作用。我想知道的是什么可行。我应该在setValues()
函数中放置什么,以便可以切换对象中的相关项目?
更新
我的问题基于我正在创建的上下文。这是代码:
import React, { createContext, useState } from 'react'
export const FormContext = createContext()
const initialState = {
noLabels: false,
formik: false,
}
export const FormProvider = ({ children }) => {
const [values, setValues] = useState(initialState)
return (
<FormContext.Provider value={{ ...values }}>
{children}
</FormContext.Provider>
)
}
我想做的就是添加一个toggleValues
函数-像这样:
import React, { createContext, useState } from 'react'
export const FormContext = createContext()
const initialState = {
noLabels: false,
formik: false,
}
export const FormProvider = ({ children }) => {
const [values, setValues] = useState(initialState)
const toggleValues = setValues({...values, XXXXXXXX })
return (
<FormContext.Provider value={{ ...values, toggleValues }}>
{children}
</FormContext.Provider>
)
}
我正在尝试找出要输入XXXXXXXX的内容。
第二次更新
我正在尝试找到一种解决方案,该解决方案不需要要求我指定对象键的名称。而是会自动查看Form
组件上的props名称,并对照对象的键检查它们。如果它们匹配,则将切换该项目。
答案 0 :(得分:1)
您可以尝试使用useEffect
,例如noLabels
更改的副作用:
const initialValues = {
noLabels: false,
useFormik: false
};
const CustomForm = ({ noLabels, useFormik }) => {
const [values, setValues] = useState(initialValues);
useEffect(() => {
setValues({ noLabels, useFormik });
}, [noLabels, useFormik]);
return <Checkbox checked={values.noLabels}>noLabels</Checkbox>;
};
export default function App() {
const [labelIsOn, setLabelIsOn] = useState(true);
return (
<FlexBox>
<CustomForm noLabels />
<CustomForm noLabels={labelIsOn} />
<Button onClick={() => setLabelIsOn(p => !p)}>Toggle Label Is On</Button>
</FlexBox>
);
}
答案 1 :(得分:0)
类似这样的事情应该适合您的情况
const [ innitial, setInitial] = useState({
noLabels: false,
useFormik: false
})
function toggle() {
setInitial(props ? {...innitial, noLabels: true} : {...innitial, noLabels: false})
}
```
Then you can tie the toggle function to your form
答案 2 :(得分:0)
这是一种无需指定键即可在toggleValues函数中进行切换的方法。只需在调用toggleValues时传递要切换的键值即可。
我还创建了一个自定义钩子,并在其中添加了初始状态和toggleValues函数。分开逻辑。
const initialState = {
noLabels: false,
useFormik: false,
toggleValues: () => {}
};
function useForm() {
const [values, setValues] = useState(initialState);
const toggleValues = name => {
setValues(value => ({ ...value, ...{ [name]: !value[name] } }));
};
return [values, toggleValues];
}
const FormContext = createContext();
const FormProvider = ({ children }) => {
const [values, toggleValues] = useForm();
const { noLabels } = values;
return (
<FormContext.Provider
value={{ ...values, toggleValues }}
>
{children(values, toggleValues)}
</FormContext.Provider>
);
};
function App() {
return (
<FormProvider>
{(values, toggleValues) => {
const { noLabels } = values;
console.log(values);
return (
<>
<input
type="checkbox"
value={noLabels}
onChange={() => toggleValues("noLabels")}
/>
{noLabels || <label>noLabels</label>}
</>
);
}}
</FormProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);