React-Apollo - 渲染在 getDerivedStateFromProps 之前被调用
React-Apollo - render getting called before getDerivedStateFromProps
我有一个包含用户验证表单的组件。该组件在挂载时运行 graphql 查询。在 Verification 组件中,我需要使用 graphql 查询中的数据来设置状态,以便我可以使用它来更新任何值,然后将它们与表单一起提交。从那以后,我了解到 getDerivedStateFromProps
并且正在努力从该数据填充新状态。但是,数据在 DOM 中不可用。就好像 render
在 getDerivedStateFromProps
.
之前被调用一样
组件如下:
class Verification extends React.Component {
constructor(props) {
super(props);
this.state = {
company: {
legalName: ''
},
openCorporatesCompany: {}
};
}
handleLegalNameChange = (legalName) => {
let company = _.cloneDeep(this.state.company);
company.legalName = legalName;
this.setState({
company
})
};
static getDerivedStateFromProps(next, prev) {
let newState = _.cloneDeep(prev);
let {openCorporates: {getEntityAttribute}} = next;
if (getEntityAttribute && getEntityAttribute.value) {
let openCorporatesCompany = JSON.parse(getEntityAttribute.value);
let company = _.cloneDeep(newState.company);
company.legalName = openCorporatesCompany.name;
newState.openCorporatesCompany = openCorporatesCompany;
newState.company = company;
return newState;
}
return null;
}
render() {
console.log(this.state);
return (
<Input
label='Legal Name'
placeholder='Legal entity name...'
type='text'
subtext='Use the name your customers or clients will recognize'
onChange={this.handleLegalNameChange}
value={this.state.legalName}
/>
);
}
}
export const VerificationContainer = compose(
connect(mapStateToProps, mapDispatchToProps)
graphql(GetEntityAttributeQuery, {
name: "openCorporates",
options: (props) => ({
variables: {
entityId: props.currentEntity.id,
type: EntityAttributes.TypeOpenCorporates
}
})
})
)(Verification);
render
中 console.log(this.state)
的控制台输出如下所示:
如您所见,字段在 company.legalName
中的状态得到更新。但是,它永远不会填充到输入框中:
为什么输入没有更新为新状态?就好像渲染在 getDerivedStateFromProps
.
之前被调用一样
我知道你在 React 和组件更新方面的挣扎,但我想没有绝对的方法可以摆脱它; 80% 我猜你应该尝试任何不同的生命周期方法。过去有 componentWillReceiveProps 用于异步调用,但由于它被标记为不安全(我猜)你应该尝试 getDerivedStateFromProps(props, state)
getDerivedStateFromProps(props, state) {
console.log("*************** PROPS:", props);
let { openCorporates: { getEntityAttribute } } = props;
if (getEntityAttribute && getEntityAttribute.value) {
let openCorporatesCompany = JSON.parse(getEntityAttribute.value);
let company = _.cloneDeep(this.state.company);
company.legalName = openCorporatesCompany.name;
this.setState({
openCorporatesCompany,
company
})
}
}
考虑到我没有 运行 代码段。
感谢@Charlie 的回答:
static getDerivedStateFromProps(props, state) {
let newState = _.cloneDeep(state);
let { openCorporates: { getEntityAttribute } } = props;
if (getEntityAttribute && getEntityAttribute.value) {
let openCorporatesCompany = JSON.parse(getEntityAttribute.value);
let company = _.cloneDeep(newState.company);
company.legalName = openCorporatesCompany.name;
newState.openCorporatesCompany = openCorporatesCompany;
newState.company = company;
}
return newState;
}
我有一个包含用户验证表单的组件。该组件在挂载时运行 graphql 查询。在 Verification 组件中,我需要使用 graphql 查询中的数据来设置状态,以便我可以使用它来更新任何值,然后将它们与表单一起提交。从那以后,我了解到 getDerivedStateFromProps
并且正在努力从该数据填充新状态。但是,数据在 DOM 中不可用。就好像 render
在 getDerivedStateFromProps
.
组件如下:
class Verification extends React.Component {
constructor(props) {
super(props);
this.state = {
company: {
legalName: ''
},
openCorporatesCompany: {}
};
}
handleLegalNameChange = (legalName) => {
let company = _.cloneDeep(this.state.company);
company.legalName = legalName;
this.setState({
company
})
};
static getDerivedStateFromProps(next, prev) {
let newState = _.cloneDeep(prev);
let {openCorporates: {getEntityAttribute}} = next;
if (getEntityAttribute && getEntityAttribute.value) {
let openCorporatesCompany = JSON.parse(getEntityAttribute.value);
let company = _.cloneDeep(newState.company);
company.legalName = openCorporatesCompany.name;
newState.openCorporatesCompany = openCorporatesCompany;
newState.company = company;
return newState;
}
return null;
}
render() {
console.log(this.state);
return (
<Input
label='Legal Name'
placeholder='Legal entity name...'
type='text'
subtext='Use the name your customers or clients will recognize'
onChange={this.handleLegalNameChange}
value={this.state.legalName}
/>
);
}
}
export const VerificationContainer = compose(
connect(mapStateToProps, mapDispatchToProps)
graphql(GetEntityAttributeQuery, {
name: "openCorporates",
options: (props) => ({
variables: {
entityId: props.currentEntity.id,
type: EntityAttributes.TypeOpenCorporates
}
})
})
)(Verification);
render
中 console.log(this.state)
的控制台输出如下所示:
如您所见,字段在 company.legalName
中的状态得到更新。但是,它永远不会填充到输入框中:
为什么输入没有更新为新状态?就好像渲染在 getDerivedStateFromProps
.
我知道你在 React 和组件更新方面的挣扎,但我想没有绝对的方法可以摆脱它; 80% 我猜你应该尝试任何不同的生命周期方法。过去有 componentWillReceiveProps 用于异步调用,但由于它被标记为不安全(我猜)你应该尝试 getDerivedStateFromProps(props, state)
getDerivedStateFromProps(props, state) {
console.log("*************** PROPS:", props);
let { openCorporates: { getEntityAttribute } } = props;
if (getEntityAttribute && getEntityAttribute.value) {
let openCorporatesCompany = JSON.parse(getEntityAttribute.value);
let company = _.cloneDeep(this.state.company);
company.legalName = openCorporatesCompany.name;
this.setState({
openCorporatesCompany,
company
})
}
}
考虑到我没有 运行 代码段。
感谢@Charlie 的回答:
static getDerivedStateFromProps(props, state) {
let newState = _.cloneDeep(state);
let { openCorporates: { getEntityAttribute } } = props;
if (getEntityAttribute && getEntityAttribute.value) {
let openCorporatesCompany = JSON.parse(getEntityAttribute.value);
let company = _.cloneDeep(newState.company);
company.legalName = openCorporatesCompany.name;
newState.openCorporatesCompany = openCorporatesCompany;
newState.company = company;
}
return newState;
}