【问题标题】:React state updating but not rendering on child component反应状态更新但不在子组件上呈现
【发布时间】:2018-06-28 17:45:41
【问题描述】:

我知道状态正在更新,因为 1.“正在加载...”正在消失,我可以通过控制台记录 this.state.images 来查看数组。然而,当状态更新和加载进行时,搜索栏会显示,但 CardList 中的卡片不会。

当我搜索正确的字符串时,它们确实会出现,但之前不会。

如果我将 this.state.images 传递给 CardList,它们会完美显示。但是,当我移动到过滤图像时,它们只会在过滤时显示。

有什么想法吗?提前致谢。

class App extends Component {

  constructor() {
    super();
    this.state = {
      images:[],
      searchfield: ''
    }
  }

  getLabels = (image) => {
    const AuthKey = key.key;
    const res = axios.post(`https://vision.googleapis.com/v1/images:annotate?key=${AuthKey}`, {
      requests: [
        {
          image:{
            source:{
              imageUri: `http://storage.googleapis.com/${image}`
            }
          },
          features:[
            {
              type:"LABEL_DETECTION",
              maxResults:10
            }
          ]
        }
      ]
    });

    res.then(function (response) {
      const results = response.data.responses[0].labelAnnotations;
      const ex = results.map(result => {
        return result.description;
      }); 
      return ex;
    });

    return res;

  };

  componentDidMount() {
      imageFiles.imageFiles.forEach(img => {
        this.getLabels(img).then(result => {
          const results = result.data.responses[0].labelAnnotations;
          const labels = results.map(result => {
          return result.description;
        });
        //Add new values to the state 
        this.setState({images:[...this.state.images, {img, labels}]});
      });
    })
  }

  onSearchChange = (event) => {
    this.setState({searchfield: event.target.value});
  }

  render() {
    const filteredImages = this.state.images.filter(image => {
      return image.labels.includes(this.state.searchfield.toLowerCase());
    });
    // Create an array of objects to store the image path and the labels detected from Google Vision
    if (this.state.images.length === 0) {
      return <h1>Loading...</h1>
    } else {
      return (
        <Grid className="App">
          <SearchBox searchChange={this.onSearchChange}/>
          <CardList images={filteredImages} />
        </Grid>
      )}
  }

}

export default App;

【问题讨论】:

  • 您的labels 是什么样的?也许你也必须在这些上使用toLowerCase()image.labels.some(label =&gt; label.toLowerCase() === this.state.searchfield.toLowerCase())
  • @Tholle 已正确指出。我知道这是唯一的错误
  • 在组件状态下添加过滤图像。并在 onSearchChange 函数中移动您的过滤器逻辑,并从那里为过滤图像调用 setstate。现在,当您传递过滤后的图像时,它应该可以执行您想要的操作。如果您需要完整的答案,请告诉我。
  • @ManojYadav 我试过了,但我认为我做错了什么。请问我可以得到更完整的答案吗?
  • 问题是在您输入搜索词之前,filteredImages 是空的。不知道为什么它没有完全填充过滤图像并删除那些不适合查询的图像。

标签: javascript reactjs setstate


【解决方案1】:
 class App extends Component {

      constructor() {
        super();
        this.state = {
          images:[],
          searchfield: '',
          filteredImages:[]
        }
      }

      getLabels = (image) => {
        const AuthKey = key.key;
        const res = axios.post(`https://vision.googleapis.com/v1/images:annotate?key=${AuthKey}`, {
          requests: [
            {
              image:{
                source:{
                  imageUri: `http://storage.googleapis.com/${image}`
                }
              },
              features:[
                {
                  type:"LABEL_DETECTION",
                  maxResults:10
                }
              ]
            }
          ]
        });

        res.then(function (response) {
          const results = response.data.responses[0].labelAnnotations;
          const ex = results.map(result => {
            return result.description;
          }); 
          return ex;
        });

        return res;

      };

      componentDidMount() {
          imageFiles.imageFiles.forEach(img => {
            this.getLabels(img).then(result => {
              const results = result.data.responses[0].labelAnnotations;
              const labels = results.map(result => {
              return result.description;
            });
            //Add new values to the state 
            this.setState({images:[...this.state.images, {img, labels}]});
this.setState({filteredImages:[...this.state.images, {img, labels}]});
          });
        })
      }

      onSearchChange = (event) => {
        this.setState({searchfield: event.target.value});
        let filteredImages = this.state.images.filter(image => {
            return image.labels.includes(this.state.searchfield.toLowerCase());
          });
        this.setState({filteredImages});
      }

      render() {

        // Create an array of objects to store the image path and the labels detected from Google Vision
        if (this.state.images.length === 0) {
          return <h1>Loading...</h1>
        } else {
          return (
            <Grid className="App">
              <SearchBox searchChange={this.onSearchChange}/>
              <CardList images={this.state.filteredImages} />
            </Grid>
          )}
      }

    }

    export default App;

【讨论】:

  • 谢谢。我得到了同样的结果。我认为问题在于,在您输入搜索词之前,filteredImages 是空的。它应该从 this.state.images 中完全填充 filteredImages 数组,然后过滤掉那些与查询不匹配的数组。相反,它看起来像是开始为空并添加与查询匹配的元素?不过,感谢您抽出宝贵的时间,非常感谢。
  • 在这种情况下,您需要在 componentDidMount 中为过滤后的图像调用 setState 以及 this.setState({images:[...this.state.images, {img, labels}]}) ;用它更新代码。
猜你喜欢
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-10
  • 2021-05-19
  • 2020-03-13
相关资源
最近更新 更多