javascript - React,模态数据仅在第二次打开时正确呈现
问题描述
我有一个反应模式,它有一组复选框。这些复选框“选中”的值来自 API 调用。但问题是,它们只会在第二次点击时更新。
我试图设置一个条件以在加载复选框组之前等待获取数据。所以 mi app 看起来像这样
在我加载数据的父组件中
我设置了一个 permUpdated 状态,等于 false,但是一旦加载数据,我将其设置为 true
getPermissionsValue() {
API.get('/user/' + this.state.rowId + '/permission')
.then(response => {
this.setState({
permissionValue: response.data,
permUpdated: true
}, () => {
// console.log(this.state.permissionValue)
});
})
}
该状态作为道具传递给作为模态的子组件
<EditUserModal permUpdated={this.state.permUpdated} ....>
在孩子的渲染中,我曾经有这个,它工作正常但没有更新
<div className="checkboxesIn">
{permissionsPrint}
</div>
{permissionsPrint}
是我要呈现的复选框。所以我把它设置为:
<div className="checkboxesIn">
{this.props.permUpdated ? {permissionsPrint} : null}
</div>
但是这样我的应用程序就会崩溃。
× 错误:对象作为 React 子级无效(找到:带有键 {permissionsPrint} 的对象)。如果您打算渲染一组子项,请改用数组。
这就是 permissionPrint 的样子
(5) [{…}, {…}, {…}, {…}, {…}]
0: {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …}
1: {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …}
2: {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …}
3: {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …}
4: {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …}
length: 5
__proto__: Array(0)
这就是我创建它的方式
var permissionsPrint = [];
var valuesData = []
this.props.permissionValue.map(e => valuesData = Object.entries(e))
console.log(valuesData)
for (let i = 1; i < valuesData.length; i++) {
//console.log(valuesData[i][0]) //name of the permission
//console.log(valuesData[i][1]) //true false
permissionsPrint.push(<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id={valuesData[i][0]} value={valuesData[i][1]} defaultChecked={valuesData[i][1]} onChange={this.props.handleChangePermissions} />
<label class="form-check-label" for={"inlineCheckbox" + i} style={{ textTransform: "capitalize" }}>{valuesData[i][0]}</label>
</div>)
编辑:模态的整个代码
class EditUserModal extends React.Component {
constructor(props) {
super(props);
this.state = {
userId: ""
};
console.log("PROOPPSS");
console.log(props);
console.log(this.props.permUpdated);
}
componentDidUpdate() {}
componentDidMount() {
this.setState({
email: this.props.email
});
}
render() {
var permissionsPrint = [];
var valuesData = [];
this.props.permissionValue.map(e => (valuesData = Object.entries(e)));
console.log(valuesData);
for (let i = 1; i < valuesData.length; i++) {
//console.log(valuesData[i][0]) //name of the permission
//console.log(valuesData[i][1]) //true false
permissionsPrint.push(
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="checkbox"
id={valuesData[i][0]}
value={valuesData[i][1]}
defaultChecked={valuesData[i][1]}
onChange={this.props.handleChangePermissions}
/>
<label
class="form-check-label"
for={"inlineCheckbox" + i}
style={{ textTransform: "capitalize" }}
>
{valuesData[i][0]}
</label>
</div>
);
}
console.log("this is THE PROP OF PERMUPDATED");
console.log(this.props.permUpdated);
if (!this.props.show) {
return null;
}
return (
<div className="modalBg">
<div className="flex-container">
<div id="open-modal" className="modal-window">
<form onSubmit={this.props.handleSubmit}>
<div>
{/* <p>{this.props.userId}</p> */}
<FontAwesomeIcon
className="closeIcon"
onClick={this.props.close}
icon={faTimesCircle}
/>
<br></br>
{this.props.userDataUpdated ? (
<Alert
className="alertEditUser"
variant="success"
dismissible
onClose={this.props.handleDismiss}
>
User Data Updated
</Alert>
) : null}
{this.props.passwordMatchFailure ? (
<Alert
className="alertEditUser"
variant="danger"
dismissible
onClose={this.props.handleDismiss}
>
Passwords do not match
</Alert>
) : null}
{this.props.emailCantBeBlank ? (
<Alert
className="alertEditUser"
variant="danger"
dismissible
onClose={this.props.handleDismiss}
>
Email Cant Be Blank
</Alert>
) : null}
<div class="form-group emailgroup">
<label for="exampleFormControlInput1">
Change Email Address
</label>
<input
type="email"
class="form-control"
placeholder="name@example.com"
value={this.props.email}
onChange={this.props.handleChangeMail}
/>
</div>
{/* <div class="form-group emailgroup">
<label for="exampleFormControlInput1">Old Password</label>
<input type="password" class="form-control" />
</div> */}
<div class="form-group emailgroup">
<label for="exampleFormControlInput1">New Password</label>
<input
type="password"
class="form-control"
placeholder="Input new password"
onChange={this.props.handleChangePass}
/>
<input
type="password"
class="form-control"
placeholder="Confirm new password"
onChange={this.props.handleChangePass2}
style={{ marginTop: "5px" }}
/>
</div>
<div class="form-group emailgroup">
<label for="exampleFormControlInput1">User Permissions</label>
<br></br>
<div className="checkboxes">
<div className="checkboxesIn">
{/* {permissionsPrint} */}
{this.props.permUpdated ? permissionsPrint : null}
</div>
</div>
</div>
<div class="text-center">
<button class="btn btn-primary " type="submit">
Update
</button>
</div>
</div>
</form>
</div>
</div>
</div>
);
}
}
export default EditUserModal;
管理员的完整代码
import React, { Component } from "react";
import API from "../services/axiosObject.js";
import "./css/Admin.css";
import Reactable from "reactable";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEdit } from "@fortawesome/free-regular-svg-icons";
import EditUserModal from "./EditUserModal";
export default class Admin extends Component {
constructor(props) {
super(props);
this.state = {
retracted: false,
userList: [],
showModal: false,
rowId: "",
selectedMail: "",
password: "",
password2: "",
userDataUpdated: false,
passwordMatchFailure: false,
emailCantBeBlank: false,
permissionValue: [],
permUpdated: false
};
this.getUserList = this.getUserList.bind(this);
this.showModal = this.showModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.handleChangeMail = this.handleChangeMail.bind(this);
this.handleChangePass = this.handleChangePass.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleDismiss = this.handleDismiss.bind(this);
this.handleChangePermissions = this.handleChangePermissions.bind(this);
this.getPermissionsValue = this.getPermissionsValue.bind(this);
}
componentDidUpdate() {}
componentDidMount() {
this.getUserList();
}
handleChangeMail = evt => {
this.setState({
selectedMail: evt.target.value
});
};
handleChangePass = evt => {
this.setState({
password: evt.target.value
});
};
handleChangePass2 = evt => {
this.setState({
password2: evt.target.value
});
};
handleChangePermissions = evt => {
console.log(this.state.permissionValue);
console.log("id: " + evt.target.id);
var idu = evt.target.id;
var checked = evt.target.checked;
console.log("checked: " + evt.target.checked);
var data = this.state.permissionValue[0];
console.log("data1");
console.log(data);
data[idu] = checked;
console.log("data2");
console.log(data);
this.setState({
permissionValue: [data]
});
};
getUserList() {
API.get("/userlist").then(response => {
this.setState(
{
userList: response.data
},
() => {
console.log(this.state.userList);
}
);
});
}
handleSubmit(event) {
event.preventDefault();
//console.log("updating")
//console.log("email: " + this.state.selectedMail)
var email = this.state.selectedMail;
var password = this.state.password;
var password2 = this.state.password2;
var permissionValue = this.state.permissionValue;
console.log("....");
console.log("password: " + this.state.password);
console.log("password2: " + this.state.password2);
console.log("....");
console.log("userId: " + this.state.rowId);
console.log("email: " + email);
if (password2 != password || email == "") {
console.log("P2: " + password2);
console.log("P1: " + password);
if (password2 != password) {
console.log("CONTRASEÑAS DISTINTAS");
this.setState({
passwordMatchFailure: true
});
} else {
this.setState({
emailCantBeBlank: true
});
}
} else {
console.log("ENTRA EN EL ELSE");
if (password == undefined || password2 == undefined) {
password = "";
password2 = "";
}
API.post("/user/update/" + this.state.rowId, {
email,
password,
permissionValue
}).then(response => {
console.log(permissionValue);
if (response.data == "user data updated") {
this.setState(
{
userDataUpdated: true
},
() => {
console.log(this.state.userDataUpdated);
}
);
}
});
}
}
handleDismiss() {
console.log("HANDLING DISMISSSSSSSSSSSSSSSSS");
this.setState({
userDataUpdated: false,
passwordMatchFailure: false,
emailCantBeBlank: false
});
}
showModal(rowId, rowEmail) {
this.setState(
{
showModal: true,
rowId: rowId,
selectedMail: rowEmail
},
() => {
this.getPermissionsValue();
}
);
}
closeModal() {
console.log("CLOOOOOOSSSSINNGGGGGGGGGGGGG");
this.setState(
{
showModal: false
},
() => {
// console.log("clicked closeModal")
// console.log(this.state.showModal)
}
);
}
getPermissionsValue() {
API.get("/user/" + this.state.rowId + "/permission").then(response => {
this.setState(
{
permissionValue: response.data,
permUpdated: true
},
() => {}
);
});
}
render() {
var users = this.state.userList;
const Table = Reactable.Table,
Td = Reactable.Td,
Tr = Reactable.Tr;
if (users.length === 0) {
return <p>loading</p>;
}
return (
<div class="maincontainer">
<div className="content-landing">
<button
class="btn btn-primary "
style={{ float: "right", marginRight: "20px" }}
onClick={() => this.props.history.push("/register")}
>
New user
</button>
<Table
className="table"
filterable={["Email"]}
itemsPerPage={8}
currentPage={0}
sortable={true}
>
{users.map(row => {
return (
<Tr className={row.className}>
<Td column="Email">{row.email}</Td>
<Td column="Edit">
<FontAwesomeIcon
className="editIcon"
onClick={() => this.showModal(row.id, row.email)}
icon={faEdit}
/>
</Td>
</Tr>
);
})}
</Table>
<EditUserModal
permUpdated={this.state.permUpdated}
permissionValue={this.state.permissionValue}
emailCantBeBlank={this.state.emailCantBeBlank}
userDataUpdated={this.state.userDataUpdated}
handleChangePermissions={this.handleChangePermissions}
passwordMatchFailure={this.state.passwordMatchFailure}
handleDismiss={this.handleDismiss}
show={this.state.showModal}
close={this.closeModal}
userId={this.state.rowId}
email={this.state.selectedMail}
handleChangePass={this.handleChangePass}
handleChangePass2={this.handleChangePass2}
handleChangeMail={this.handleChangeMail}
handleSubmit={this.handleSubmit}
/>
</div>
</div>
);
}
}
解决方案
在这里{this.props.permUpdated ? {permissionsPrint} : null}
,我认为您不需要花括号围绕permissionsPrint
它应该是:
{this.props.permUpdated ? permissionsPrint : null}
{permissionsPrint}
这与{permissionsPrint: permissionsPrint}
which 是具有相同键名和值名的 Object 相同,其中 value 是与键名同名的变量。
推荐阅读
- c++ - Qt 在 QWidget::update() 中崩溃
- arrays - 选择数组的元素而不在 awk 中指定数组
- bash - 在历史记录中查找后续命令
- c# - C# 统一脚本使用库 UnityNativeGallery 在 android 库中截取和保存屏幕截图
- powershell - Powershell 排序由分号分隔的字符串元素
- c++ - 转换迭代器和 const_iterators
- android-imageview - Android-Image-Cropper 权限 READ/WRITE_EXTERNAL_STORAGE 问题
- javascript - 如果选择了选项,则显示自定义内容
- java - 如果列标签同名,如何在 Spark 中使用 java 解析 XML
- javascript - 输入值不发送到火力基地