【问题标题】:Dynamic input value in ReactReact 中的动态输入值
【发布时间】:2021-03-05 00:35:21
【问题描述】:

所以我有一个片段工厂被传递到一个 Display 组件中。片段具有输入元素。在 Display 内部,我有一个 onChange 处理程序,它获取输入的值并将其存储在 contentData[e.target.id] 中。这可行,但切换显示哪个片段会删除它们的值,我宁愿它没有。所以我试图通过将状态对象传递给工厂来设置它们的值。我以这种复杂的方式来适应我的测试框架。我需要在任何组件之外定义片段并作为道具传递给 Display,并且我需要它们全部共享一个状态对象。

我的问题是设置值。我可以传入状态对象(contentData),但为了确保值转到 contentData 数据对象中的正确键,我试图用输入的 id 对其进行硬编码。除了定义片段的地方不存在 contentData,所以我收到一个错误,提示无法引用未定义的 dataObj 上的特定键。

我需要找到一种方法将输入值设置为 contentData[e.target.id]。谢谢。

定义片段的文件。可惜不是组件。

const fragments = (onChangeHandler, dataObj) => [
    <Fragment key="1">
        <input 
            type="text" 
            id="screen1_input1" 
            onChange={onChangeHandler}
            value={dataObj['screen1_input1']} // this doesn't work
        />
        one
    </Fragment>,
    <Fragment key="2">
        <input 
            type="text" 
            id="screen2_input1" 
            onChange={onChangeHandler}
            value={dataObj['screen2_input1']}
        />
        two
    </Fragment>
]

显示.js

const Display = ({ index, fragments }) => {
    const [contentData, setContentData] = useState({})
    
    const onChange = e => {     
        // set data
        const newData = {
            ...contentData,
            [e.target.id]: e.target.value
        }
        setContentData(newData)
    };

  return (
      <Fragment>{fragments(onChange, contentData)[index]}</Fragment>
  );
};

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    在与您交谈后,我决定修改我的回复。问题主要在于其他人可能在这些任意片段中提供的实现。

    您已经说过您可以不受限制地定义传入的道具,这很有帮助,我们需要做的是获取它们传入的这些节点,并用我们的 onChange 覆盖它们的 onChange 以及值:

    const RecursiveWrapper = props => {
        const wrappedChildren = React.Children.map(
            props.children,
            child => {
                if (child.props) {
                    return React.cloneElement(
                        child,
                        {
                            ...child.props,
                            onChange: props.ids.includes(child.props.id) ? child.props.onChange ? (e) => {
                              child.props.onChange(e);
                              props.onChange(e);
                            } : props.onChange : child.props.onChange,
                            value: props.contentData[child.props.id] !== undefined ? props.contentData[child.props.id] : child.props.value,
                        },
                        child.props.children 
                        ? (
                            <RecursiveWrapper 
                              ids={props.ids} 
                              onChange={props.onChange} 
                              contentData={props.contentData}
                            >
                              {child.props.children}
                            </RecursiveWrapper>
                          ) 
                        : undefined
                    )
                }
                return child
            }
        )
        return (
            <React.Fragment>
                {wrappedChildren}
            </React.Fragment>
        )
    }
    
    const Display = ({ index, fragments, fragmentIDs }) => {
        const [contentData, setContentData] = useState(fragmentIDs.reduce((acc, id) => ({ 
    ...acc, [id]: '' }), {}));
        
        const onChange = e => {     
            setContentData({
                ...contentData,
                [e.target.id]: e.target.value
            })
        };
    
      const newChildren = fragments.map(fragment => <RecursiveWrapper onChange={onChange} ids={fragmentIDs} contentData={contentData}>{fragment}</RecursiveWrapper>);
    
      return newChildren[index];
    };
    

    此代码概述了总体思路。在这里,我们将片段视为节点数组,而不是生成它们的函数。然后我们获取片段并对其进行映射,并用包含我们所需道具的节点替换旧节点。然后我们按计划渲染它们。

    【讨论】:

    • 是的,我明白你的意思,问题是显示必须是通用的,所以我不能提前设置键。它需要从给定的任何片段中动态读取它们。
    • 这有点像鸡蛋交易之前的鸡,如果您有某种方式知道会有多少片段或某种方式生成 ID 列表,那么它很容易使其通用在您尝试创建片段列表之前。
    • 或多或少,如果你要让数据从父级流向子级,你不能让片段有自己的ID,它需要是另一个一路走来。
    • 我不喜欢特定的 id,如果它们需要由父母设置,那很好。你能展示一下如何实现吗?
    • 详细了解您的错误来自何处,请问您使用的是什么测试框架导致您需要预定义这些片段?我并不完全理解您的问题,但是 React 的组合模型使您的要求变得有些困难。
    猜你喜欢
    • 2021-03-27
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    相关资源
    最近更新 更多