简体   繁体   English

重新构造组件时,不会更新在构造函数中创建的元素

[英]Element created in constructor not updated when component rerenders

Why is the <select> I create in the constructor not updated when I pick another flavor in it? 为什么在构造器中创建的<select>在选择其他样式时没有更新? The other select , as well as the text, is updated. 另一个select以及文本被更新。

 class ConstructorComponent extends React.Component { constructor() { super(); this.state = { icecream: 'vanilla', }; this.select = ( <select value={this.state.icecream} onChange={this.onChange} > <option value="chocolate">Chocolate</option> <option value="vanilla">Vanilla</option> <option value="strawberry">Strawberry</option> </select> ); } onChange = event => { this.setState({ icecream: event.target.value, }); }; render() { return ( <div> Icecream flavor: {this.state.icecream} <br /> {this.select} <br /> <select value={this.state.icecream} onChange={this.onChange} > <option value="chocolate">Chocolate</option> <option value="vanilla">Vanilla</option> <option value="strawberry">Strawberry</option> </select> </div> ); } } ReactDOM.render( <ConstructorComponent />, document.getElementById('container') ); 
 <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="container"> <!-- This element's contents will be replaced with your component. --> </div> 

I made it work by cloning this.select in render() like so: {React.cloneElement(this.select, {value: this.state.icecream})} 我通过在render()克隆this.select使其工作,如下所示: {React.cloneElement(this.select, {value: this.state.icecream})}

But making this.select a method instead, as suggested by several answers to my question is probably better. 但是按照我的问题的几个答案的建议,改为使用this.select方法可能更好。 I'll see what works best with my actual code, and not just this dumbed down example :) 我将看到最适合我的实际代码的东西,而不仅仅是这个愚蠢的例子:)

Because this.state.icecream in your first select is interpreted only once, when you define this.select in the constructor. 因为在构造函数中定义this.select时,第一次选择中的this.state.icecream仅被解释一次。 So when your ConstructorComponent rerenders a second time when its state changes, there is nothing to update in your first select. 因此,当您的ConstructorComponent状态发生第二次改变时,您的第一选择中没有任何要更新的内容。

You need to define this.select as a function returning the <select> , like this: 您需要将this.select定义为返回<select>的函数,如下所示:

this.select = () => {
  return (
    <select
      value={this.state.icecream}
      onChange={this.onChange}
    >
      <option value="chocolate">Chocolate</option>
      <option value="vanilla">Vanilla</option>
      <option value="strawberry">Strawberry</option>
    </select>
  )
}

And call this.select() in the render. 并在渲染器中调用this.select()

You can also create a reference to the <select> in the render by using the prop ref : 您还可以使用prop ref来创建对渲染中<select>ref

render() {
  <select
    value={this.state.icecream}
    onChange={this.onChange}
    ref={select => (this.select = select)}  // the magic happens here
  >
    <option value="chocolate">Chocolate</option>
    <option value="vanilla">Vanilla</option>
    <option value="strawberry">Strawberry</option>
  </select>
}

In doing so, you don't need to define this.select as a function in your constructor. 这样,您无需在构造函数中将this.select定义为一个函数。

The first select doesn't work because it's only ever rendered once, in the constructor. 第一次选择不起作用,因为在构造函数中仅被渲染一次。 The second select works because it's re-rendered every time the app state updates. 第二个选择之所以起作用,是因为每次应用状态更新时都会重新呈现它。

If it helps, don't think of JSX elements as "instances" of actual HTML elements. 如果有帮助,请不要将JSX元素视为实际HTML元素的“实例”。 Think of them as a simple means of how you want your app to look in relation to your state. 将它们视为您希望应用程序相对于您的状态外观的一种简单方法。 If my state is "a", then I render a select with "a", and if my state is "b", then I render a select with "b", and so on. 如果我的状态为“ a”,则使用“ a”呈现选择,如果我的状态为“ b”,则使用“ b”呈现选择,依此类推。

The first select box on the page is only rendered in the constructor which is called just once, thus the component will always remain the same as it does when it is first rendered. 页面上的第一个选择框仅在一次调用的构造函数中呈现,因此该组件将始终与首次呈现时保持相同。 In other words it is static. 换句话说,它是静态的。 The second select box is going to be re-rendered each time the component is updated. 每次更新组件时,都会重新渲染第二个选择框。

In order to fix your code you can change your line in the constructor to a function: 为了修复您的代码,您可以将构造函数中的行更改为函数:

this.select = () => (
  <select
    value={this.state.icecream}
    onChange={this.onChange}
  >
    <option value="chocolate">Chocolate</option>
    <option value="vanilla">Vanilla</option>
    <option value="strawberry">Strawberry</option>
  </select>
);

Then change your return statement to call this function: 然后更改您的return语句以调用此函数:

<br />
  {this.select()}
<br />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 组件重新渲染时数组为空 - array empty when component rerenders 更改道具后,React会重新渲染组件吗 - Does React rerenders component when a prop is changed 将函数作为道具发送给它时,React 组件会重新渲染 - React component rerenders when sending function as props to it 当组件重新渲染时,React SVG 消失 - React SVG disappearing when component rerenders ReactNative 在用户打开页面时重新渲染组件 - ReactNative rerenders component when the user opens the page 当组件在 React Native 中重新渲染时,动态不透明度不会改变 - Dynamic Opacity not changing when component rerenders in react native React:父组件重新渲染时,子组件是否总是重新渲染? - React: Do children always rerender when the parent component rerenders? 当在BrowserRouter组件中更新道具时,未调用react-router Route组件构造函数 - react-router Route component constructor is not called when props are updated in BrowserRouter component 反应:当新的道具传递给组件时,构造函数中声明的this.var不会更新 - React: this.var declared in constructor is not updated when new props is passed to component 更新Redux的商店后,React.js何时重新提供组件? - When does React.js rerenders a component after I update the Redux's store?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM