首页 > 解决方案 > onChange 事件后组件未重新渲染

问题描述

我已经检查了有关重新渲染的不同主题的先前答案,但找不到解决此问题的正确方法。在选择框上触发 onChange 事件后,我试图重新渲染组件。

我有一个包含 5 个用户的用户列表,我将它们分成性别数组。所以我有一个男性阵列和一个女性阵列。我试图在 onChange 事件之后显示选定的性别用户列表。

我试图在组件中使用'key' attr,但它没有用。

这是我的 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);

这是我的列表组件:

import React from 'react';

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

export default List;

当我在 handleChange 中检查控制台时,道具(用户)正在正确传递,但不是很直观的结果。

标签: javascriptreactjs

解决方案


状态和生命周期

您应该使用state/setState作为在 react 上触发渲染的一种方式。

setState()将组件状态的更改加入队列,并告诉 React 该组件及其子组件需要使用更新的状态重新渲染。

这里的主要思想是将性别值存储在状态中,因为我们希望在该值更改时呈现

  1. 在您的构造函数上添加初始状态

    constructor(props) {
         super(props);
         this.state = {
             gender: []
         }
     }
    
  2. 使用setState()新值更新 onChange 事件。此函数将通知异步响应需要重新渲染。您需要重构一些逻辑以仅通过更新状态来清理更改处理程序。请记住 setState 是异步的,可能是误解的根源。

      handleChange = (e) => {
         setState({gender: e.target.value});
     }
    
  3. 最终版本应如下所示:

    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()filter根据选定的性别执行。无需存储男性和女性,因为在大多数情况下性能应该没问题。


推荐阅读