React + Styled Components:每个渲染setState重置所有组件

时间:2019-06-19 03:16:47

标签: reactjs

我偶然发现了使用React + Styled Components的顶级谜团。我完全不知所措。

这是我的组成部分:

import React from 'react';
import styled from "styled-components";

class SearchBar extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            searchStr: '',
            isEditing: false,
            isSearching: false,
            isIdle: true,
            activeMode: 'search'
        };
    }

    onChange=(e)=>{
        console.log("on change input");
        this.setState( {
            ...this.state
        }, () => {
            // nada...
        });
    };


    render () {

        const SearchBarStyle = styled.div`
            height: 85%;
            `;

        return (
            <SearchBarStyle>
                <input type="text" onChange={this.onChange} placeholder="Search"/>
            </SearchBarStyle>
        );
    }
}


export default SearchBar;

问题是这样的:只要我开始输入input,就会调用setState。发生这种情况时,<SearchBarStyle>下的所有内容都会重置!我的第一个键入字符被删除,输入控件从头开始,显示占位符提示...

这是令人弯腰的东西:

如果我将<SearchBarStyle>替换为简单的div OR ,则我从不致电setState,就不会出现此问题。我可以自由键入...以某种方式,在使用样式化组件构建的组件上调用setState会将其完全重置!

威士忌-探戈-狐步舞!?

4 个答案:

答案 0 :(得分:3)

检查此代码

问题1。未设置输入值。输入元素应为

<input
          value={this.state.searchStr}
          type="text"
          onChange={this.onChange}
          placeholder="Search"
        />

问题2。目标输入值未设置为状态,您的onChange处理程序应为

onChange = e => {
    this.setState({ searchStr: e.target.value });
  };

https://codesandbox.io/s/heuristic-montalcini-mkiyq

答案 1 :(得分:1)

请勿将state值用作input值,也不会通过state将新值分配给e.target.value

onChange = (e) => {
  console.log("on change input");
  // e.target.value contains the updated value of the input
  this.setState({
    searchStr: e.target.value
  }, () => {
    console.log('state updated', this.state);
  });
};

searchStr中的state分配为值

<input
  type="text"
  value={this.state.searchStr}
  onChange={this.onChange}
  placeholder="Search"
/>

要保持输入焦点,请在SearchBarStyles组件外部上方定义SearchBar

const SearchBarStyle = styled.div`
  height: 85%;
`;


class SearchBar extends React.Component {
  ..

答案 2 :(得分:1)

  1. 在课程上方声明SearchBarStyle。 每次在render()组件中进行更新时,在SearchBar中进行声明都会重新渲染该组件。
import React from "react";
import styled from "styled-components";

const SearchBarStyle = styled.div`
  height: 85%;
`;

class SearchBar extends React.Component {
...
  1. 更新状态的方式不正确。应该是:
onChange = e => {
  console.log("on change input")
  this.setState({
    searchStr: e.target.value
  }, () => {

  });
};
  1. 将状态值分配给输入框。
  <input type="text" onChange={this.onChange} value={this.state.searchStr} placeholder="Search"/>

答案 3 :(得分:1)

这里您使用的是Uncontrolled Components,因此,每setState的组件都会重新呈现,最终失去了旧的价值。

要解决此问题,您必须使用Controlled Components,即将input的value属性设置为状态值,例如

<input type="text" onChange={this.onChange} placeholder="Search" value={this.state.searchStr} />