React子组件无法重新呈现

时间:2018-02-02 15:30:35

标签: reactjs typescript

我有以下(瘦身)组件:

export class StringExpression extends React.Component {
  render() {
    const fieldOptions = getFieldOptions(this.props.expression);

    console.log(fieldOptions); //I can see fieldOptions changes here

    return (
       <Expression {...this.props} className="block-container">
         {fieldOptions ?
           <Popover>
             <PopoverTarget>
               {expression.value}
             </PopoverTarget>
             <PopoverContent id={expression.id}>
               <SelectList fields={fieldOptions} />
             </PopoverContent>
           </Popover> :
           <InlineEdit />
         }
       </Expression>
    );
  };
}

export class SelectList extends React.Component {
  render() {
    return (
      <ul>
        {this.props.fields.map((field, index) => {
          return <li key={field} onClick={this.handleClick}>{field}</li>;
        }
      </ul>
    );
  };
}

当我更改StringExpression的输入时,我看到该组件重新渲染。这些更改会改变fieldOptionsSelectList的支柱。但是,SelectList不会重新渲染。我尝试在this.forceUpdate()上添加StringExpression(我认为这不明智)。我还在componentWillReceiveProps()添加了SelectList,以查看fieldOptions更改时是否会触发,但事实并非如此。

如何在SelectList更改时让fieldOptions重新呈现?

更新 我更新了帖子以分享我的StringExpression的其他代码。如您所见,SelectList基于fieldOptions有条件地显示。 SelectListfieldOptionsnull更改为string[]时呈现SelectList,反之亦然。这是因为InlineEdit卸载所以fieldOptions可以挂载。如果string[]从一个SelectList更改为另一个libraryDependencies += specs2 % Test,则import org.specs2.mutable.Specification import play.api.Application import play.api.test.WithApplicationLoader import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.{Await, Future} import scala.concurrent.duration.DurationInt class RackRepositorySpec extends Specification { "RackRepository" should { "work as expected" in new WithApplicationLoader { val app2dao = Application.instanceCache[RackRepository] val rackRepository: RackRepository = app2dao(app) Await.result(rackRepository.delete("r-1"), 3 seconds) Await.result(rackRepository.delete("r-2"), 3 seconds) Await.result(rackRepository.delete("r-3"), 3 seconds) val testRacks = Set( RackRow("r-1", 0.2F, System.currentTimeMillis()), RackRow("r-2", 0.5F, System.currentTimeMillis()), RackRow("r-3", 0.8F, System.currentTimeMillis()) ) Await.result(Future.sequence(testRacks.map(rackRepository.insert)), 3 seconds) val storedRacks = Await.result(rackRepository.list(), 3 seconds) storedRacks.toSet must contain(testRacks) } } } 不会重新呈现。

2 个答案:

答案 0 :(得分:0)

您正在使用<!-- Allow links to web pages to open in a browser --> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> 。如果我猜对了,key={field}是一个具有不同属性的对象(它有field吗?)。因此,每个id获得的keyli

键应该对每个数组元素都是唯一的,在这种情况下它们不是,所以React并不真正知道如何渲染它们,特别是如果每​​个都有相同的键。

尝试使用[object Object]或其他一些独特属性。如果该字段不存在唯一密钥,则可以使用key={field.id}

答案 1 :(得分:0)

对于我看到的代码,解释必须是选择列表组件上的prop字段在运行时不会更改。你的问题似乎在其他地方。 向我们提供有关您的代码的更多信息