简体   繁体   English

onChange事件后组件未重新呈现

[英]Component not re-rendering after onChange event

I've checked the previous answer on different topics about re-rendering but couldn't find a proper way to fix this. 我已经检查了有关重新渲染的不同主题的先前答案,但是找不到解决此问题的正确方法。 I am trying to re-render a component after the onChange event is fired on the select box. 我试图在选择框上触发onChange事件后重新呈现组件。

I have a userlist with 5 users and I separated them into genders array. 我有一个有5个用户的用户列表,并将它们分成性别数组。 So I have a males array and a females array. 所以我有一个男性阵列和一个女性阵列。 I am trying to show the selected gender user list after the onChange event. 我正在尝试在onChange事件之后显示所选的性别用户列表。

I tried to use the 'key' attr in component but it didn't work. 我试图在组件中使用“关键”属性,但没有用。

here is my UserList container: 这是我的UserList容器:

import React, { Component } from "react";
import ReactDOM from "react-dom";

import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import List from '../components/List.jsx'

class UserList extends Component {

    constructor(props) {
         super(props);
     }

    renderUser = (toMap) => {
        console.log(toMap);
    return (
            <List key = {toMap.length} users = {toMap}/>
        );
  }

    renderSelect = () => {
    return (
            <select id="gender" onChange={this.handleChange}>
        <option value="select">Select a gender</option>
        <option value="males">Males</option>
        <option value="females">Females</option>
      </select>
        );
  }

    handleChange = (e) => {
        const {userList,males,females} = this.props;
        const gender = e.target.value;

        if(gender == 'males'){
            return this.renderUser(males);
        }else if(gender == 'females'){
            return this.renderUser(females);
        }
        return this.renderUser(userList);
    }

  render() {
        const {isLoading,error,userList} = this.props;

         return (
             <div>
                 {this.renderSelect()}
           <ul>
                    {this.renderUser(userList)}
           </ul>
                </div>
     );
    }
}

export default connect(mapStateToProps)(UserList);

here is my List Component: 这是我的列表组件:

import React from 'react';

const List = ({users}) => (
    <ul>
        {users.map( (user,index) => (
          <li key = {index} >{user.email}</li>
        ))}
    </ul>
);

export default List;

the props (users) are passing correctly when I check the console in handleChange but can't quite a visual result. 当我在handleChange中检查控制台时,道具(用户)正确通过,但视觉效果不佳。

State and Lifecycle 状态与生命周期

You should use state / setState as a way to trigger a rendering on react . 您应该使用state / setState作为在react上触发渲染的一种方式。

setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. setState()使更改进入组件状态并告诉React该组件及其子级需要使用更新后的状态重新呈现。

Main idea here is to store gender value in state, as we want to render when this value is changed 这里的主要思想是将性别值存储在状态中,因为我们想在更改此值时进行渲染

  1. Add a initial state on your contructor 在构造器上添加初始状态

     constructor(props) { super(props); this.state = { gender: [] } } 
  2. Update onChange event , using setState() with a new value. 使用具有新值的setState() 更新onChange事件 This function will notify asynchroniously react about the need to rerender. 此功能将异步通知有关重新渲染的需求。 You need to refactor a bit your logic to clean you change handler with just updating state. 您需要重构一下逻辑,以仅通过更新状态来清理更改处理程序。 Keep in mind setState is async, might be source of misunderstanding. 请记住,setState是异步的,可能会引起误解。

      handleChange = (e) => { setState({gender: e.target.value}); } 
  3. Final version should look something like this : 最终版本应如下所示:

     import React, { Component } from "react"; import ReactDOM from "react-dom"; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import List from '../components/List.jsx' class UserList extends Component { constructor(props) { super(props); this.state = { gender: null }; } renderUser = (toMap) => { return ( <List key = {toMap.length} users = {toMap.filter(user => this.state.gender ? user.gender === this.state.gender : true)}/> ); } renderSelect = () => { return ( <select id="gender" onChange={this.handleChange}> <option value="select">Select a gender</option> <option value="males">Males</option> <option value="females">Females</option> </select> ); } handleChange = (e) => { this.setState({ gender: e.target.value}) } render() { const {isLoading,error,userList} = this.props; return ( <div> { this.renderSelect() } <ul> { this.renderUser(userList) } </ul> </div> ); } } 

    renderUser() will perform a filter based on selected gender. renderUser()将根据所选性别执行filter No need to store males and females as performance should be fine for most case. 无需存储男性和女性,因为在大多数情况下,性能应该很好。

Here is a working example of your code : https://codesandbox.io/s/new-wkgu6 这是您的代码的有效示例: https : //codesandbox.io/s/new-wkgu6

you are not setting state anywhere because of which component is not rendering again 您没有在任何地方设置状态,因为哪个组件不再渲染

setState() will always lead to a re-render unless shouldComponentUpdate() returns false. 除非shouldComponentUpdate()返回false,否则setState()将始终导致重新渲染。

More information on setState api can be found here 有关setState api的更多信息,请参见此处

https://reactjs.org/docs/react-component.html#setstate https://reactjs.org/docs/react-component.html#setstate

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM