javascript - 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 中检查控制台时,道具(用户)正在正确传递,但不是很直观的结果。
解决方案
状态和生命周期
您应该使用state/setState作为在 react 上触发渲染的一种方式。
setState()将组件状态的更改加入队列,并告诉 React 该组件及其子组件需要使用更新的状态重新渲染。
这里的主要思想是将性别值存储在状态中,因为我们希望在该值更改时呈现
在您的构造函数上添加初始状态
constructor(props) { super(props); this.state = { gender: [] } }
使用
setState()
新值更新 onChange 事件。此函数将通知异步响应需要重新渲染。您需要重构一些逻辑以仅通过更新状态来清理更改处理程序。请记住 setState 是异步的,可能是误解的根源。handleChange = (e) => { setState({gender: e.target.value}); }
最终版本应如下所示:
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
根据选定的性别执行。无需存储男性和女性,因为在大多数情况下性能应该没问题。
推荐阅读
- sequelize.js - 使用 Sequelize 关联模型的方法是否正确?
- mediawiki - 无论如何,mediawiki 页面有多个显示标题?
- spring - spring-boot-starter-quartz jdbc vs不同环境下的内存jobstore
- mediawiki - 带有斜杠的页面标题上的权限问题真的很奇怪
- c# - 是否可以配置 .net runsettings 文件以包含复杂对象?
- reactjs - 通过反应 js lodash 循环并更改字段值
- sql - 当只有两个表连接到联结表时,将四个表连接在一起
- xslt - XSLT 1.0:键在选择节点时不起作用
- docker - 如何使 docker 命令的输出静音
- java - 如何在 Spring Boot 中禁用个人健康指标?