我正在编写一个React状态组件,以处理在文本框中输入的文本,并在数据库和文本框之间保存和加载文本。我可以在文本框中输入内容,也可以将文本框中的内容保存到数据库中。当我从数据库加载到文本框时,组件的状态会更新,而(子)文本框的prop会根据Chrome中的React DevTools更新处理从父组件到文本框的传递文本。问题在于该文本框的值未重新呈现以反映新的道具。
我做了一些研究,发现状态变化时应该重新渲染React组件。我尝试使用useState()
向子组件添加状态,并且每次使用
useEffect(() => setText(propText), [propText])
它没有用。 React DevTools中的道具和状态显示了我加载的值,但组件未在文本框中显示它。也许它不是设计用来从props和state而不是用户输入中获取输入值的,但是它的onChange()事件处理函数会更新父状态,就像我尝试使用数据库访问组件一样,因此它是完全抽象的。
这是现在的子组件:
function InputTextComponent(props) {
const { parentInput, textUpdate } = props;
const [text, setText] = useState(parentInput);
useEffect(() => setText(parentInput), [parentInput]);
const onTextChange = event => {
const {
target: { value }
} = event;
textUpdate(value);
};
return (
<TextAreaGroup
placeholder={'Input text'}
name={'Input text here'}
value={text}
info={'Input text'}
onChange={event => onTextChange(event)}
/>
);
}
这是父组件:
class ParentComponent extends Component {
constructor() {
super();
this.state = {
textInput: '',
};
this.textUpdate.bind(this);
}
textUpdate = textInput => this.setState({ textInput });
render() {
const {
textInput,
} = this.state;
return (
<div className="container mt-3">
<InputTextComponent
textUpdate={this.textUpdate}
parentInput={textInput}
/>
<LoadTextsComponent
alias={alias} // alias is irrelevant part of the component
aliasUpdate={this.aliasUpdate}
skuUpdate={this.skuUpdate}
/>
</div>
);
}
}
数据库加载组件使用textUpdate()
函数。这是完整的组件:
function LoadTextsComponent(props) {
const { alias, aliasUpdate, textUpdate } = props;
const [setList, setListUpdate] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await client.get('/texts/listTexts');
aliasUpdate(result[0].alias);
setListUpdate(result);
};
fetchData();
}, []);
const loadTextsToInputBox = () => {
let aliasSet;
for (let set of setList) {
if (set.alias === alias) {
aliasSet = set.texts;
}
}
let textString = '';
for (let text of aliasSet) {
textString += text + '\n';
}
textString = textString.slice(0, -1);
textUpdate(textString);
};
return (
<div>
<ShowAliasesComponent
setList={setList}
alias={alias}
aliasUpdate={aliasUpdate}
/>
<button
disabled={!alias}
className="btn btn-primary"
onClick={() => loadTextsToInputBox()}
>
Send texts of alias {alias} to input box
</button>
</div>
);
}
真正令人困惑的是,当我在子文本框中键入内容时,父状态正确更新(向下传递函数以更新父状态),而新的prop反映在渲染中。但是,当我从数据库加载组件调用相同的函数时,什么也没发生。