我有三个组成部分。首先是一个EditableField组件,我想在显示h3标签和用户可以输入更多文本的输入之间切换(这部分有效)。 OnBlur,然后输入应该更改回带有更新文本的h3(也可以工作)并调度后端请求以持久保存h3的新值(此部分不起作用)。 EditableField呈现为Card组件,Card Component呈现在CardList组件中,该组件包含卡阵列的后端数据。
我很难搞清楚1)哪个组件应该控制调度后端请求以保持新的文本值? 2)根据#1的答案,如何访问输入文本的更新值?顺便说一句,我已经在邮递员中证实我当前的路线是有效的。我会在我的组件之后发布它。
class EditableField extends Component {
constructor(props) {
super(props);
this.state = {
text: this.props.text
}
}
handleChange = (e) => {
this.setState({ text: e.target.value });
}
render() {
const { text } = this.state;
if(this.props.isEditing) {
return (
<input value={ text } type='text'
onChange={ this.handleChange }
onBlur={this.props.handleToggle} autoFocus />
)
}
return (
<h3 onClick={ this.props.handleToggle }
{text}
</h3>
)
}
}
export default EditableField;
class Card extends Component {
constructor(props) {
super(props);
this.state = {
isEditing: false
};
}
handleToggle = () => {
this.setState({ isEditing: !this.state.isEditing });
this.handleBlur(this.props._id, this.props.title);
// the above handleBlur does not work
}
handleBlur = async (id, text) => {
const res = await axios.put(`/api/surveys/${id}`, text);
}
render() {
const { isEditing } = this.state;
return (
<div className="col-sm-12 col-md-12 col-lg-6 my-3">
<div className="card">
<div className="card-body">
<div className="card-title">
<EditableField
text={this.props.title}
isEditing={isEditing}
handleToggle={this.handleToggle} />
</div>
</div>
</div>
</div>
)
}
}
export default Card;
export class CardList extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false
}
}
componentDidMount() {
this.props.fetchCards();
}
renderSurveys() {
return this.props.cards.reverse().map(({ _id, title, body, dateSent, yes, no}) => {
return (
<Card key={_id} title={title}
body={body} dateSent={dateSent}
yes={yes} no={no} _id={_id}
onDelete={ () => {
this.props.deleteSurvey(_id)
}} />
)
});
}
render() {
const { isLoading } = this.props;
return (
<div className="container">
{ isLoading && <LoadingIndicator /> }
<div className="row">
{this.renderSurveys()}
</div>
</div>
);
}
}
function mapStateToProps({ cards: { cards, isLoading }}) {
return {
cards,
isLoading
}
}
export default connect(mapStateToProps, { fetchCards, deleteCard })(CardList);
app.put('/api/surveys/:surveyId', async (req, res) => {
const { title } = req.body;
try {
await Survey.updateOne({ _id: req.params.surveyId }, {
$set: { title }
})
.exec();
res.send('ok').status(200);
}
catch(e) {
res.send(e).status(400);
}
});