为什么订阅完成后我的数据会消失?
Why does my data disappear when a subscription goes through?
订阅完成后,为什么我的数据未定义?
我想弄清楚我的 props.data.allLocations 的 undefined 是从哪里来的。任何帮助将不胜感激。
//高阶分量
export const LocationList = graphql(
gql`
query ($site: ID!) {
allLocations(
filter: {
site: {
id:$site
}
}
) {
id
name
}
}
`,
{
options: (ownProps)=>({
variables: {
site: ownProps.site
},
}),
//props were injected from the JSX element
props: props => {
return {
data: props.data,
subscribeToData: params => {
return props.data.subscribeToMore({
document:
gql`
subscription newLocations {
Location {
mutation
node {
id
name
}
}
}
`,
variables: {
//Empty for now
//site: props.site,
},
updateQuery: (previousState, {subscriptionData}) => {
if (!subscriptionData.data) {
return previousState;
}
var newArray =[subscriptionData.data.Location.node].concat(previousState.allLocations)
var newState = {
...previousState,
allLocations: [
{
...subscriptionData.data.Location.node
},
...previousState.allLocations
],
};
return newState
}
})
},
}
},
onError: (err) => console.error(err)
} )(EntityList)
//列表组件
class EntityList extends Component {
componentWillReceiveProps(newProps) {
if (!newProps.data.loading) {
console.log(newProps)
if (this.subscription && this.props.hasOwnProperty('subscribeToData')) {
if (newProps.data.allLocations !== this.props.data.allLocations) {
console.log("Resubscribe")
// if the todos have changed, we need to unsubscribe before resubscribing
this.subscription()
} else {
console.log('else')
// we already have an active subscription with the right params
return
}
}
this.subscription = this.props.subscribeToData(newProps)
}}
render () {
if (this.props.data.loading) {
return (<div>Loading</div>)
}
var Entities = [];
for(var key in this.props.data) {
if(this.props.data[key] instanceof Array){
Entities = Entities.concat(this.props.data[key])
//console.log(this.props.data[key])
}
}
return (
<div className='w-100 flex justify-center bg-transparent db' >
<div className='w-100 db' >
{Entities.map((entity) =>
(
<EntityListView
user={this.props.user}
key={entity.id}
entityId={entity.id}
name={entity.name}
profilePic={(entity.profilePic)?entity.profilePic.uuid : this.props.defaultPic.uuid}
clickFunc={this.props.clickFunc}
/>
))}
</div>
</div>
)
}
}
感谢所有对此进行调查的人。
按照@nburk 的建议,我通过拆分我的查询来让它工作。
我能够通过创建自己的高阶组件来保持它的模块化。
如果有人感兴趣:
const Subscriber = (document, config) => {
return (WrappedComponent) => {
return class extends Component {
constructor(props) {
super(props)
this.state={}
this.subscription = null
}
componentWillReceiveProps(nextProps) {
console.log(nextProps)
if (!this.subscription && !nextProps.data.loading) {
console.log("Sucess")
let { subscribeToMore } = this.props.data
this.subscription = [subscribeToMore(
{
document: document,
updateQuery: (previousResult, { subscriptionData }) => {
console.log(subscriptionData)
var newResult = [subscriptionData.data[config.modelName].node].concat(previousResult[config.propName])
console.log(newResult)
return {
//"allItems"
[config.propName]: newResult,
}
},
onError: (err) => console.error(err),
}
)]
this.setState({});
}
}
render () {
if (this.props.data.loading) {
return (<div>Loading</div>)
}
return (
<WrappedComponent {...this.props} />
)
}
}
}
}
export default Subscriber
/*prop config = {
propName: "string", //allItems // from query
//so I do not have to parse the gql query (would have to recieve from parent)
modelName: "string" //Item
// from subscribe //so I do not have to parse the gql subscribe
}
*/
我现在这样包装我的组件:
export const LocationList = graphql(gql`...,
{options: (ownProps)=>({
variables: {
site: ownProps.site
}})})(
Subscriber(gql`...,
propName:"allLocations",
modelName:"Location",
)(EntityList))
谢谢
订阅完成后,为什么我的数据未定义? 我想弄清楚我的 props.data.allLocations 的 undefined 是从哪里来的。任何帮助将不胜感激。
//高阶分量
export const LocationList = graphql(
gql`
query ($site: ID!) {
allLocations(
filter: {
site: {
id:$site
}
}
) {
id
name
}
}
`,
{
options: (ownProps)=>({
variables: {
site: ownProps.site
},
}),
//props were injected from the JSX element
props: props => {
return {
data: props.data,
subscribeToData: params => {
return props.data.subscribeToMore({
document:
gql`
subscription newLocations {
Location {
mutation
node {
id
name
}
}
}
`,
variables: {
//Empty for now
//site: props.site,
},
updateQuery: (previousState, {subscriptionData}) => {
if (!subscriptionData.data) {
return previousState;
}
var newArray =[subscriptionData.data.Location.node].concat(previousState.allLocations)
var newState = {
...previousState,
allLocations: [
{
...subscriptionData.data.Location.node
},
...previousState.allLocations
],
};
return newState
}
})
},
}
},
onError: (err) => console.error(err)
} )(EntityList)
//列表组件
class EntityList extends Component {
componentWillReceiveProps(newProps) {
if (!newProps.data.loading) {
console.log(newProps)
if (this.subscription && this.props.hasOwnProperty('subscribeToData')) {
if (newProps.data.allLocations !== this.props.data.allLocations) {
console.log("Resubscribe")
// if the todos have changed, we need to unsubscribe before resubscribing
this.subscription()
} else {
console.log('else')
// we already have an active subscription with the right params
return
}
}
this.subscription = this.props.subscribeToData(newProps)
}}
render () {
if (this.props.data.loading) {
return (<div>Loading</div>)
}
var Entities = [];
for(var key in this.props.data) {
if(this.props.data[key] instanceof Array){
Entities = Entities.concat(this.props.data[key])
//console.log(this.props.data[key])
}
}
return (
<div className='w-100 flex justify-center bg-transparent db' >
<div className='w-100 db' >
{Entities.map((entity) =>
(
<EntityListView
user={this.props.user}
key={entity.id}
entityId={entity.id}
name={entity.name}
profilePic={(entity.profilePic)?entity.profilePic.uuid : this.props.defaultPic.uuid}
clickFunc={this.props.clickFunc}
/>
))}
</div>
</div>
)
}
}
感谢所有对此进行调查的人。 按照@nburk 的建议,我通过拆分我的查询来让它工作。 我能够通过创建自己的高阶组件来保持它的模块化。 如果有人感兴趣:
const Subscriber = (document, config) => {
return (WrappedComponent) => {
return class extends Component {
constructor(props) {
super(props)
this.state={}
this.subscription = null
}
componentWillReceiveProps(nextProps) {
console.log(nextProps)
if (!this.subscription && !nextProps.data.loading) {
console.log("Sucess")
let { subscribeToMore } = this.props.data
this.subscription = [subscribeToMore(
{
document: document,
updateQuery: (previousResult, { subscriptionData }) => {
console.log(subscriptionData)
var newResult = [subscriptionData.data[config.modelName].node].concat(previousResult[config.propName])
console.log(newResult)
return {
//"allItems"
[config.propName]: newResult,
}
},
onError: (err) => console.error(err),
}
)]
this.setState({});
}
}
render () {
if (this.props.data.loading) {
return (<div>Loading</div>)
}
return (
<WrappedComponent {...this.props} />
)
}
}
}
}
export default Subscriber
/*prop config = {
propName: "string", //allItems // from query
//so I do not have to parse the gql query (would have to recieve from parent)
modelName: "string" //Item
// from subscribe //so I do not have to parse the gql subscribe
}
*/
我现在这样包装我的组件:
export const LocationList = graphql(gql`...,
{options: (ownProps)=>({
variables: {
site: ownProps.site
}})})(
Subscriber(gql`...,
propName:"allLocations",
modelName:"Location",
)(EntityList))
谢谢