gpt4 book ai didi

reactjs - 为动态表单字段抽象 React Hooks

转载 作者:行者123 更新时间:2023-12-04 02:39:43 25 4
gpt4 key购买 nike

我正在使用 react-hook-form用于创建多步动态大型表单(超过 70 个字段)的库。我的大部分表单字段都是动态的(用户可以通过单击 + 按钮添加/删除更多字段)。为了实现这一点,我使用 react-hooks 并为每个动态字段添加一个钩子(Hook)。但我觉得我的代码不够抽象,可能有更聪明的方法来做到这一点。下面是我的表单的示例屏幕截图:

enter image description here

钩子(Hook)和表单字段的各自代码在这里:

         // hooks
const [sizes, setSizes] = React.useState([0]);
const [formats, setFormats] = React.useState([0]);

const [counter, setCounter] = React.useState(1);

// buttons
const addSizesFieldset = () => {
setSizes(prevIndexes => [...prevIndexes, counter]);
setCounter(prevCounter => prevCounter + 1);
};

const removeSizesFieldset = index => () => {
setSizes(prevIndexes => [
...prevIndexes.filter(item => item !== index)
]);
setCounter(prevCounter => prevCounter - 1);
};


const addFormatsFieldset = () => {
setFormats(prevIndexes => [...prevIndexes, counter]);
setCounter(prevCounter => prevCounter + 1);
};

const removeFormatsFieldset = index => () => {
setFormats(prevIndexes => [
...prevIndexes.filter(item => item !== index)
]);
setCounter(prevCounter => prevCounter - 1);
};


// form field arrays
{sizes.map(index => {
const fieldName = `sizes[${index}]`;
return (
<fieldset name={fieldName} key={fieldName} >
<h4>Sizes:</h4>
<label>
Size:
<input
type="text"
placeholder="Input"
name={`${fieldName}.size`}
ref={register}

/>
</label>

<button type="button" onClick={addSizesFieldset}>
+
</button>
<button type="button" onClick={removeSizesFieldset(index)}>
-
</button>
</fieldset>
);
})}
{formats.map(index => {
const fieldName = `formats[${index}]`;
return (
<fieldset name={fieldName} key={fieldName} >
<h4>Formats:</h4>
<label>
Format:
<input
type="text"
placeholder="Input"
name={`${fieldName}.format`}
ref={register}

/>
</label>

<button type="button" onClick={addFormatsFieldset}>
+
</button>
<button type="button" onClick={removeFormatsFieldset(index)}>
-
</button>
</fieldset>
);
})} ´´

想象一下,您正在为 70 个字段执行这些 Hook 瞬间和 const add/remove...Fieldset 函数。对我来说,这似乎有太多重复,但除了“React 可以处理多个钩子(Hook),所以不用担心”评论之外,我找不到任何解决方案或新想法。

如果你想在codesandbox上尝试你的想法,我也准备了下面的代码:

https://codesandbox.io/s/react-hook-form-wizard-form-yzno5

最佳答案

也许如果你使用useReducer,如果你有多个状态会更好

例子

const initialState = {
counter: 1,
sizes: [0],
formats: [0],
};

function reducer(state, action) {
switch (action.type) {
case 'add':
return {
...state,
counter: state.counter + 1,
[action.typeObject]: [...state.sizes, state.counter + 1]
};
case 'remove':
return {
...state,
counter: state.counter - 1,
[action.typeObject]: [...state.sizes.filter(item => item !== action.index)]
};
default:
return state;
}
}

/***/

const [stateReducer, dispatch] = React.useReducer(reducer, initialState);

/***/

const addSizesFieldset = () => {
dispatch({ type: 'add', typeObject: 'sizes' })
};

const removeSizesFieldset = index => () => {
dispatch({ type: 'remove', typeObject: 'sizes', index })
};

const addFormatsFieldset = () => {
dispatch({ type: 'add', typeObject: 'formats' })
};

const removeFormatsFieldset = index => () => {
dispatch({ type: 'remove', typeObject: 'formats', index })
};

测试一下

这是我通过 fork 你的代码的简单实现: https://codesandbox.io/s/react-hook-form-wizard-form-1h4yq


编辑:

您甚至可以通过在参数中添加“typeObject”来删除 2 个函数:

const addFieldset = field => () => {
dispatch({ type: 'add', typeObject: field })
};

const removeFieldset = (index, field) => () => {
dispatch({ type: 'remove', typeObject: field, index })
};

关于reactjs - 为动态表单字段抽象 React Hooks,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59952677/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com