我的组件接收到正确的 props(使用“listDescAdd”后应该为“null”),但输入中的值没有改变。
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withTranslation } from 'react-i18next';
import { listDescAdd, listDescEdit, listRemove, listDescCurrent } from 'redux/actions';
import { connect } from 'react-redux';
import FormContext from 'context/FormContext';
import plus from 'img/icons/plus.svg';
import minus from 'img/icons/minus.svg';
import Select from 'react-select';
import { objt } from 'utils';
export class ListInputDescriptionItem extends Component {
constructor (props) {
super(props);
this.state = { description: '', training: '' };
this.handleChangeTraining = this.handleChangeTraining.bind(this);
this.handleChangeDescription = this.handleChangeDescription.bind(this);
this.handleEditDescription = this.handleEditDescription.bind(this);
this.handleEditTraining = this.handleEditTraining.bind(this);
this.handleAdding = this.handleAdding.bind(this);
this.currentTextInput = React.createRef();
}
getRequired () {
if (this.props.required === true) {
return <span className="tw-font-semibold tw-text-red-500 tw-text-sm tw-ml-2">{this.props.t('required')}</span>;
}
}
// handle input text change
handleChangeTraining (data, context) {
if (data) {
var training = data.value;
} else {
var training = undefined;
}
this.props.listDescCurrent(this.props.name, this.props?.input?.[context.name]?.[this.props.name + '_current']?.value, training, context.name)
}
handleChangeDescription (e, context) {
var { value } = e.target;
this.props.listDescCurrent(this.props.name, value, this.props?.input?.[context.name]?.[this.props.name + '_current']?.training, context.name)
}
// handle sending new entry
// clear state when sending
handleAdding (context) {
if (this.props?.input?.[context.name]?.[this.props.name + '_current']?.value && this.props?.input?.[context.name]?.[this.props.name + '_current']?.training) {
this.props.listDescAdd(
this.props.name,
this.props?.input?.[context.name]?.[this.props.name + '_current']?.value,
this.props?.input?.[context.name]?.[this.props.name + '_current']?.training,
context.name);
this.currentTextInput.current.value = '';
}
}
// handle sending on enter
// use state and handleAdding
_handleKeyDown (e, context) {
if (e.key === 'Enter') {
if (this.props?.input?.[context.name]?.[this.props.name + '_current']?.value && this.props?.input?.[context.name]?.[this.props.name + '_current']?.training) {
this.props.listDescAdd(
this.props.name,
this.props?.input?.[context.name]?.[this.props.name + '_current']?.value,
this.props?.input?.[context.name]?.[this.props.name + '_current']?.training,
context.name);
this.forceUpdate();
}
}
}
// handle edit of existing value
handleEditDescription (e, context) {
this.props.listDescEdit(this.props.name, e.target.value, this.getValue(context), context.name, this.props.item.id);
}
handleEditTraining (data, context) {
this.props.listDescEdit(this.props.name, this.getValueDescription(context), ((data && data.value) || null), context.name, this.props.item.id);
}
getValue (context = null, current = false) {
if(current === true) {
if(this.props?.input?.[context.name]?.[this.props.name + '_current']?.training) {
return this.getOptions().filter(option => option.value === this.props?.input?.[context.name]?.[this.props.name + '_current']?.training)[0];
}
return null;
}
if (context === null) {
if (this.state.training) {
return this.getOptions().filter(option => option.value === this.state.training)[0];
} else {
return null;
}
}
if (this.props.input && this.props.input[context.name] && this.props.input[context.name][this.props.name] && this.props.input[context.name][this.props.name].filter(i => i.id === this.props.item.id).length !== 0) {
return this.getOptions().filter(option => {
return option.value === this.props.input[context.name][this.props.name].filter(i => i.id === this.props.item.id)[0].training;
})[0];
} else {
return null;
}
}
getValueDescription (context, current = false) {
if(current === true) {
return this.props?.input?.[context.name]?.[this.props.name + '_current']?.value;
}
if (this.props.input && this.props.input[context.name] && this.props.input[context.name][this.props.name] && this.props.input[context.name][this.props.name] && this.props.input[context.name][this.props.name].filter(i => i.id === this.props.item.id).length !== 0) {
return this.props.input[context.name][this.props.name].filter(i => i.id === this.props.item.id)[0].value;
} else {
return undefined;
}
}
getOptions () {
var options = this.props.options ? this.props.options.map((option) => {
return {
value: option.id,
label: objt(option)
};
}) : {};
return options;
}
renderInput (context) {
if (this.props.type === 'add') {
return (
<div className="tw-flex tw-flex-row tw-w-full">
<div className="tw-flex tw-flex-col tw-flex-1">
<input
key={999999}
ref={this.currentTextInput}
type={this.props.type}
id={this.props.name}
placeholder="Description"
className="focus:tw-outline-none focus:tw-shadow-outline tw-bg-gray-300 tw-py-2 tw-px-3 tw-flex-1"
style={{ height: '38px' }}
value={this.getValueDescription(context, true)}
onChange={(e) => {
this.handleChangeDescription(e, context);
}}
onKeyDown={(e) => {
this._handleKeyDown(e, context);
}} />
<Select
key={9999999}
options={this.getOptions()}
isClearable={true}
value={this.getValue(context, true)}
name={this.props.name}
onChange={(data) => {
this.handleChangeTraining(data, context);
}}
styles={{
control: (provided, state) => ({
...provided,
backgroundColor: '#e2e8f0'
}),
menu: (provided, state) => ({
...provided,
zIndex: '9999'
})
}}
classNamePrefix="select" />
</div>
<div onClick={(e) => {
this.handleAdding(context);
}} className="tw-bg-green-500 tw-cursor-pointer tw-flex tw-flex-row tw-justify-center tw-items-center tw-h-full" style={{ width: '38px' }}>
<img src={plus} className="w-1/2" />
</div>
</div>
);
} else {
return (
<div className="tw-flex tw-flex-row tw-w-full">
<div className="tw-flex tw-flex-col tw-flex-1">
<input
type={this.props.type}
id={this.props.name}
placeholder="Description"
className="tw-text-black focus:tw-outline-none focus:tw-shadow-outline tw-bg-gray-300 tw-py-2 tw-px-3 tw-flex-1"
style={{ height: '38px' }}
value={this.getValueDescription(context)}
onChange={(e) => { this.handleEditDescription(e, context); }}
/>
<Select
options={this.getOptions()}
isClearable={true}
value={this.getValue(context)}
name={this.props.name}
onChange={(data) => {
this.handleEditTraining(data, context);
}}
styles={{
control: (provided, state) => ({
...provided,
backgroundColor: '#e2e8f0'
}),
menu: (provided, state) => ({
...provided,
zIndex: '9998',
color: 'black'
}),
menuList: (provided, state) => ({
...provided,
zIndex: '9999'
})
}}
classNamePrefix="select" />
</div>
<div onClick={(e) => {
this.props.listRemove(this.props.name, context.name, this.props.item.id);
}} className="tw-bg-red-500 tw-cursor-pointer tw-flex tw-flex-row tw-justify-center tw-items-center tw-h-full" style={{ width: '38px' }}>
<img src={minus} className="w-1/2" />
</div>
</div>
);
}
}
render () {
return (
<FormContext.Consumer>
{context =>
<div className={`tw-flex tw-flex-col ${this.props.size} tw-mb-3`}>
<div className="tw-flex tw-flex-row tw-w-full">
{this.renderInput(context)}
</div>
</div>
}
</FormContext.Consumer>
);
}
}
ListInputDescriptionItem.defaultProps = {
size: 'w-full',
required: true,
type: 'text'
};
ListInputDescriptionItem.propTypes = {
name: PropTypes.string.isRequired,
title: PropTypes.string,
size: PropTypes.string.isRequired,
required: PropTypes.bool,
type: PropTypes.string,
t: PropTypes.func.isRequired
};
const mapStateToProps = ({ errors, input }, ownProps) => {
return {
errors: errors,
input: input
};
};
export default connect(mapStateToProps, { listDescAdd, listDescEdit, listRemove, listDescCurrent })(withTranslation(['input'])(ListInputDescriptionItem));
import { HANDLE_CHANGE, CLEAR_FORM, LIST_ADD, LIST_EDIT, LIST_REMOVE, LIST_DESC_ADD, LIST_DESC_EDIT, LIST_CURRENT, LIST_DESC_CURRENT } from '../actionTypes';
import produce from 'immer';
const input = (state = { listId: 0 }, action) => {
switch (action.type) {
case HANDLE_CHANGE: {
const { name, value, form } = action.payload;
if (!state[form]) {
return produce(state, draft => {
draft[form] = {};
draft[form][name] = value;
});
} else {
return produce(state, draft => {
draft[form][name] = value;
});
}
}
case LIST_CURRENT: {
const { name, value, form } = action.payload;
if (!state[form]) {
return produce(state, draft => {
draft[form] = {};
draft[form][name + '_current'] = value;
draft.listId++;
});
} else {
return produce(state, draft => {
draft[form][name + '_current'] = value;
});
}
}
case LIST_ADD: {
const { name, value, form } = action.payload;
if (!state[form]) {
return produce(state, draft => {
draft[form] = {};
draft[form][name] = [{ id: draft.listId, value: value }];
draft[form][name + '_current'] = '';
draft.listId++;
});
} else {
return produce(state, draft => {
if (!draft[form][name]) {
draft[form][name] = [];
}
draft[form][name].unshift({ id: draft.listId, value: value });
draft[form][name + '_current'] = '';
draft.listId++;
});
}
}
case LIST_EDIT: {
const { name, value, id, form } = action.payload;
return produce(state, draft => {
draft[form][name] = draft[form][name].map(item => {
if (item.id === id) {
item.value = value;
}
return item;
});
});
}
case LIST_REMOVE: {
const { name, id, form } = action.payload;
return produce(state, draft => {
draft[form][name] = draft[form][name].filter(item => item.id !== id);
});
}
case LIST_DESC_CURRENT: {
const { name, value, training, form } = action.payload;
if (!state[form]) {
return produce(state, draft => {
draft[form] = {};
draft[form][name + '_current'] = {training, value};
});
} else {
return produce(state, draft => {
draft[form][name + '_current'] = {training, value};
});
}
}
case LIST_DESC_ADD: {
const { name, value, training, form } = action.payload;
if (!state[form]) {
return produce(state, draft => {
draft[form] = {};
draft[form][name] = [{ id: draft.listId, training: training, value: value }];
draft[form][name + '_current'] = null;
draft.listId++;
});
} else {
return produce(state, draft => {
if (!draft[form][name]) {
draft[form][name] = [];
}
draft[form][name].unshift({ id: draft.listId, training: training, value: value });
draft[form][name + '_current'] = null;
draft.listId++;
});
}
}
case LIST_DESC_EDIT: {
const { name, value, training, id, form } = action.payload;
return produce(state, draft => {
draft[form][name] = draft[form][name].map(item => {
if (item.id === id) {
item.value = value;
item.training = training;
}
return item;
});
});
}
case CLEAR_FORM: {
const { form } = action.payload;
return produce(state, draft => {
delete draft[form];
});
}
default:
return state;
}
};
export default input;
因此,在输入(第一个)中,使用“listDescAdd”将“当前”输入重置为空后,输入中的值保持不变。但是,当我检查时,它显示文本输入收到了正确的道具,但没有更新显示的值。
知道如何解决这个问题吗?
答案 0 :(得分:0)
尝试使用 value={() => this.getValueDescription(context)}