如何从 React 元素(更改时)获取“关键”props?

IT技术 javascript reactjs
2021-04-19 19:50:57

我想在 select 时获取选项的值和键onChange

我知道我能得到期权的value用简单event.target.valueonChangeOption功能,但我怎么能得到key

<select onChange={this.onChangeOption} value={country}>
    {countryOptions.map((item, key) =>
        <option key={key} value={item.value}>
            {item.name}
        </option>
    )}
</select>
6个回答

您需要将键中的值作为不同的props传递。

从文档:

键用作 React 的提示,但它们不会传递给您的组件。如果您的组件中需要相同的值,请将其作为具有不同名称的 prop 显式传递:

阅读:https : //reactjs.org/docs/lists-and-keys.html

感谢您的回答,正是我需要清除我的困惑。
2021-05-24 19:50:57
这是一个糟糕的答案。它没有提出解决方案或考虑到他正在处理本机select字段,因此这可能会以某种形式使用,如果用自定义组件替换可能会中断
2021-05-25 19:50:57
感谢您的回复,我已阅读文档,但仍有疑问。这是否意味着我“必须”将键中的值作为不同的道具传递,以便我可以获得键?
2021-05-25 19:50:57
是的,就是这个意思。
2021-06-16 19:50:57

将键作为props传递显然有效,但更快的方法可能是将键作为自定义属性包含在您的 html 中。

class App extends React.Component {
  constructor(props) {
    super(props);
    this.onSelect = this.onSelect.bind(this);
  }
  onSelect(event) {
    const selectedIndex = event.target.options.selectedIndex;
        console.log(event.target.options[selectedIndex].getAttribute('data-key'));
  }

  render() {
    return ( 
      <div>
      <select onChange = {this.onSelect}>
       <option key="1" data-key="1">One</option> 
       <option key="2" data-key="2">Two</option>             </select> 
     </div>
    );
  }
}

ReactDOM.render( < App / > , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

这里的 selectedIndex 是什么?event.target.options.selectedIndex;
2021-06-15 19:50:57

想象一个这样的组件:

<Component data={[{id:'a23fjeZ', name="foo"}, ...]}` 

这使得输入列表,并在获得dataprops这是一个集合(数组对象):

function Component ( props ){
    // cached handler per unique key. A self-invoked function with a "cache" object
    const onChange = (cache => param => {
        if( !cache[param] )
            cache[param] = e => 
                console.log(param, e.target.name, e.target.value)

        return cache[param];
    }
    )({});

    return props.data.map(item =>
        <input key={item.id} name={item.name} onChange={onChange(item.id)} />
    }

}

正如您所看到的,key没有被访问,而是被传递到一个内部处理缓存柯里化函数中,以防止在重新渲染时“无休止地”创建函数。

因此,您确实需要将键<option>作为props传递给,但是由于<select>是本机字段并在内部处理更改,因此很难将键值取回。让我们一次一个问题开始,将 prop 传递到 option 可以像这样包装 option 组件并使用indexprop 作为新的 key prop 一样简单。

const CustomOption = ({ value, children, index }) => (
    <option key={index} value={value}>{value}</option>
);

另请注意,我们在上面创建了一个自定义组件包装器,以将indexprop 应用于<option />自身,因为 react 不喜欢 dom 元素上的未知 props。

现在,如果我们可以处理选项内的选定事件,我们就可以完成,但我们不能那样做。所以我们还需要进行自定义选择:

class CustomSelect extends React.Component {

    static propTypes = {
        value: PropTypes.object,
        onChange: PropTypes.func,
    }

    handleChanged = (e) => {
        const newValue = e.target.value;
        let newKey;

        // iterate through our children searching for the <CustomOption /> that was just selected
        React.children.forEach(this.children, (c) => {
            if (c.props && c.props.index && c.props.value === newValue) {
                newKey = c.props.key;
            }
        });

        this.props.onChange(e, newKey);
    }

    render() {
        return (
            <select value={this.props.value} onChange={this.handleChanged}>
                {this.props.children}
            </select>
        );
    }
}

它有两个propsvalue, 和onChange请注意,我们拦截更改事件以找到索引(键),并将其作为第二个参数传递给父级。这不是很好,但我想不出另一种简单的方法来做到这一点,同时仍然使用本机<select>元素。

请注意,您需要替换对这些新类的使用<select><optoin>使用,并在选项上分配indexprops和keyprops。

太好了,我以前没有想过这种方式。
2021-05-24 19:50:57

你可以通过任何东西value我认为这可以解决您的问题。

<select onChange={this.handleChange}>
        {this.state.countryOptions.map((item, key) =>
          <option key={key} 
            value={JSON.stringify({key, value:item.value})}>
            //passing index along with value
            {item.value}
          </option>
        )}
</select>

handleChange(e) {
    let obj = JSON.parse(e.target.value) 
   // gives object{ key:country index, value: country value}
  }
@vsync 我认为这是这里的要求。你能进一步解释你的评论吗?
2021-06-06 19:50:57
value道具必须是value,而不是一个字符串化对象的某些可憎。这与服务器无关(很可能)。这种方式已经持续了大约 20 年。其他人都做对了,但以非最佳方式实施了他们的解决方案。
2021-06-17 19:50:57