渲染组件出现问题

时间:2018-08-03 11:41:21

标签: reactjs

我具有要在其中搜索用户列表的组件。我遇到的问题是渲染前未调用我的this.state.employees。我正在使用componentDidMount来获取我的员工列表,请参见下文:

 componentDidMount() {
    if (!!this.props.employees && this.props.employees.length == 0) {
       this.props.listEmployees();
      }
    }

因此,按组件分类,此刻不返回任何员工。有谁知道做到这一点的最佳方法。

class ShareForUsers extends Component {
  constructor(props){
    super(props);
    this.state = {
      props,
      menuOpen: false,
      value: "",
      values: []
    };
  }

    componentDidMount() {
    if (!!this.props.employees && this.props.employees.length == 0) {
       this.props.listEmployees();
      }
    }

  componentWillReceiveProps(nextProps) {
    this.setState({ ...nextProps })
  }
  render() {
    if (!!this.state.employees) return <p>no employees</p>;
    console.log(this.state.employees)
    return (
      <div>
         {persons}
        {this.renderUsers}
        <TextField
          fullWidth
          value={this.state.value}
          InputProps={{
            startAdornment: this.state.values
              .concat()
              .sort(({ label: aLabel }, { label: bLabel }) => {
                if (aLabel < bLabel) return -1;
                else if (aLabel > bLabel) return 1;
                return 0;
              })
              .map(chip => (
                <InputAdornment
                  component={Chip}
                  label={chip.label}
                  onDelete={() => {
                    const value = chip;
                    this.setState(({ values: prevValues }) => {
                      const values = prevValues;
                      const idx = values.indexOf(value);
                      if (idx === -1) {
                        values.push(value);
                      } else {
                        values.splice(idx, 1);
                      }

                      return {
                        values
                      };
                    });
                  }}
                />
              ))
          }}
          onChange={evt => {
            const value = evt.target.value;
            this.setState({
              value,
              menuOpen: value.length > 0
            });
          }}
          onFocus={() =>
            this.setState(({ value }) => ({
              menuOpen: value.length > 0
            }))
          }
          onBlur={() => this.setState({})}
        />
        <div>
          {this.state.menuOpen ? (
            <Paper
              style={{
                position: "absolute",
                zIndex: 100,
                width: "100%"
              }}
            >
            {this.state.employees
                .filter(
                  employee =>
                  employee.user.email.toLowerCase().indexOf(this.state.value) > -1
                )
                .map(employee => (
                  <MenuItem
                    key={employee.value}
                    onClick={() => {
                      this.setState(({ values: prevValues }) => {
                        const values = prevValues.concat();
                        const idx = values.indexOf(employee);
                        if (idx === -1) {
                          values.push(employee);
                        } else {
                          values.splice(idx, 1);
                        }

                        return {
                          values,
                          value: "",
                          menuOpen: false
                        };
                      });
                    }}
                  >
                    {employee.label}
                  </MenuItem>
                ))}
            </Paper>
          ) : (
            ""
          )}
        </div>
      </div>
    )
  }
}

const shareForUsers = withStyles(styles)(ShareForUsers)
export default connect(
  state => state.user,
  dispatch => bindActionCreators(actionCreators, dispatch)
)(shareForUsers);

1 个答案:

答案 0 :(得分:1)

您不需要将employees保持在您的状态。您仍然可以在渲染方法中使用this.props.employees

请特别注意componentWillReceiveProps生命周期方法,该方法已标记为在以后的React版本中删除。它在React社区中启用了许多反模式,因此它们提供了替换生命周期getDerivedStateFromProps。我强烈建议您阅读此生命周期方法中的official blog post

关于代码的一些说明:

constructor(props){
    super(props);
    this.state = {
      props,
      menuOpen: false,
      value: "",
      values: []
    };
}

注释1:

您正在将“道具”置于您的状态。 绝对没有必要。无论何时需要访问状态,您都将可以访问道具。因此,将其置于您的状态中并没有好处,因为不相关的支持正在变化,因此可能会导致不必要的/意外的状态变化。

注意2:

错误的初始状态。如果您确实需要(出于某种原因),请在您的州拥有employees。然后,您必须在构造函数中正确初始化它们。

注释3:

您缺少用户正在“加载/获取”数据的反馈。到目前为止,当您进行渲染时,首先用户将看到:找不到雇员,然后在获取数据后,他们将神奇地看到屏幕。

如果您的流程本质上是“同步”的,那可能没问题,但是您的行为是异步的,因此您还必须准备遵循组件的状态

  

正在加载|错误|已加载(无数据)|已加载(已找到数据)