尝试了解Connect Component的问题,将对您有所帮助

时间:2019-12-06 20:09:54

标签: javascript node.js reactjs graphql

我正在尝试阅读以下文章,同时进行一些修改以尝试是否可以将其用于我正在学习React的一些常规摄影工作。当我单击链接时,它似乎正在通过控制台日志按预期传递ID参数。

https://read.acloud.guru/build-your-own-multi-user-photo-album-app-with-react-graphql-and-aws-amplify-374800b22e96

但是,当我尝试设置属性详细信息视图时,单击其中一项而不是我期望的详细信息页面时出现此错误:

Connect.js:410 Uncaught TypeError: this.props.children is not a function
    at Connect.render (Connect.js:410)
    at finishClassComponent (react-dom.development.js:18483)
    at updateClassComponent (react-dom.development.js:18438)
    at beginWork$1 (react-dom.development.js:20173)
    at HTMLUnknownElement.callCallback (react-dom.development.js:337)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:386)
    at invokeGuardedCallback (react-dom.development.js:439)
    at beginWork$$1 (react-dom.development.js:25768)
    at performUnitOfWork (react-dom.development.js:24682)
    at workLoopSync (react-dom.development.js:24658)
    at performSyncWorkOnRoot (react-dom.development.js:24247)
    at react-dom.development.js:12285
    at unstable_runWithPriority (scheduler.development.js:701)
    at runWithPriority$2 (react-dom.development.js:12231)
    at flushSyncCallbackQueueImpl (react-dom.development.js:12280)
    at flushSyncCallbackQueue (react-dom.development.js:12268)
    at discreteUpdates$1 (react-dom.development.js:24401)
    at discreteUpdates (react-dom.development.js:1439)
    at dispatchDiscreteEvent (react-dom.development.js:5914)
Connect.render @ Connect.js:410
finishClassComponent @ react-dom.development.js:18483
updateClassComponent @ react-dom.development.js:18438
beginWork$1 @ react-dom.development.js:20173
callCallback @ react-dom.development.js:337
invokeGuardedCallbackDev @ react-dom.development.js:386
invokeGuardedCallback @ react-dom.development.js:439
beginWork$$1 @ react-dom.development.js:25768
performUnitOfWork @ react-dom.development.js:24682
workLoopSync @ react-dom.development.js:24658
performSyncWorkOnRoot @ react-dom.development.js:24247
(anonymous) @ react-dom.development.js:12285
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
flushSyncCallbackQueueImpl @ react-dom.development.js:12280
flushSyncCallbackQueue @ react-dom.development.js:12268
discreteUpdates$1 @ react-dom.development.js:24401
discreteUpdates @ react-dom.development.js:1439
dispatchDiscreteEvent @ react-dom.development.js:5914
index.js:1406 The above error occurred in the <Connect> component:
    in Connect (at App.js:141)
    in PropertyDetailsLoader (at App.js:201)
    in Route (at App.js:199)
    in div (created by GridColumn)
    in GridColumn (at App.js:192)
    in div (created by Grid)
    in Grid (at App.js:191)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.js:190)
    in App (created by class_1)
    in class_1 (at src/index.js:7)

这是我的源代码:

import React, { Component } from 'react';

import Amplify from 'aws-amplify';
import aws_exports from './aws-exports';
import { withAuthenticator } from 'aws-amplify-react';

import { Connect } from 'aws-amplify-react';
import { API, graphqlOperation } from 'aws-amplify';
import { Grid, Header, Input, List, Segment } from 'semantic-ui-react';
import {BrowserRouter as Router, Route, NavLink} from 'react-router-dom';

Amplify.configure(aws_exports);

class NewProperty extends Component {
  constructor(props) {
    super(props);
    this.state = {
      propertyName: ''
    };
  }
    handleChange = (event) => {
      let change = {};
      change[event.target.name] = event.target.value;
      this.setState(change);
    }

    handleSubmit = async (event) => {
      event.preventDefault();
      const NewProperty = `mutation NewProperty($name: String!) {
        createProperty(input: {name: $name}) {
          id
          name
        }
      }`;
      
      const result = await API.graphql(graphqlOperation(NewProperty, {
        name: this.state.propertyName }));
          console.info(`Property Created! ${result.data.createProperty.id}`);
    }



    render() {
      return (
        <Segment>
          <Header as ='h3'>Add a new Property</Header>
          <Input
          type='text'
          placeholder='New Property Name'
          icon='plus'
          iconPosition='left'
          action={{ content:'Create', onClick: this.handleSubmit}}
          name='propertyName'
          value={this.state.propertyName}
          onChange={this.handleChange}
          />
        </Segment>
      )
    }
  
}



function makeComparator(key, order='asc') {
  return (a, b) => {
    if(!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) return 0;

    const aVal = (typeof a[key] === 'string') ? a[key].toUpperCase() : a[key];
    const bVal = (typeof b[key] === 'string') ? b[key].toUpperCase() : b[key];

    let comparison = 0;

    if (aVal > bVal) comparison = 1;
    if (aVal < bVal) comparison = -1;

    return order === 'desc' ? (comparison * -1) : comparison
  };
  
}

  class PropertiesList extends React.Component {
    propertyItems() {
      return this.props.propertys.sort(makeComparator('name')).map(property =>
          <List.Item key={property.id}>
            <NavLink to={`/propertys/${property.id}`}>{property.name}</NavLink>
          </List.Item>
        );
    }
    render(){
      return(
        <Segment>
          <Header as='h3'>My Properites</Header>
      <List divided relaxed>
        {this.propertyItems()}
        </List>
        </Segment>
      );
    }
  }

  const GetProperty = `query GetProperty($id: ID!) {
    getProperty(id: $id) {
      id
      name
    }
  }`;

  const SubcribeToNewProperties = `
      subscription OnCreateProperty {
        onCreateProperty{  
            id
            name 
        }
      }`;

  const ListPropertys = `query ListPropertys {
    listPropertys(limit: 9999) {
      items {
        id
        name
      }
    }
  }`;

  class PropertyDetails extends Component {
    render () {
      return (
        <Segment>
          <Header as='h3'>{this.props.property.name}</Header>
          <p>TODO: Allow Phtoto Uploads</p>
          <p>TODO: Show Photos attached to this Property</p>
        </Segment>
      )
    }
  }

  class PropertyDetailsLoader extends React.Component {
    render() {
      return (
        <Connect query={graphqlOperation(GetProperty, { id: this.props.id })}>
          {({ data, loading, errors }) => {
            if (loading) { return <div>Loading...</div> }
            if (errors.length > 0) { return <div>{JSON.stringify(errors)}</div> }
              if (!data.getProperty) return;
              return <PropertyDetails property={data.getProperty} />
          }
          }}
        </Connect>
      )
    }
  }

 
  class PropertyListLoader extends React.Component {

        onNewProperty = (prevQuery, newData) => {
        let updatedQuery = Object.assign({}, prevQuery);
        updatedQuery.listPropertys.items =
        prevQuery.listPropertys.items.concat([newData.onCreateProperty]);
        console.log(updatedQuery);
        return updatedQuery;
        }

    render() {
      return (
        
        <Connect query={graphqlOperation(ListPropertys)}
          subscription={graphqlOperation(SubcribeToNewProperties)}
          onSubscriptionMsg={this.onNewProperty} 
        >
          {({ data, loading, errors }) => {
            if (loading) { return <div>Loading...</div>;}
            if (errors.length > 0) {return <div>
              {JSON.stringify(errors)}</div>; }
            if (!data.listPropertys)
             return;

            return <PropertiesList propertys={data.listPropertys.items}/>;
          }}
        </Connect>
      );
    }
  } 

class App extends Component {
  render() {
    
    return (
      <Router>
        <Grid padded>
          <Grid.Column>
            <Route path="/" exact component={NewProperty}/>
            <Route path="/" exact component={PropertyListLoader}/>
            <Route
              path="/propertys/:propertyId"
              render={ () => <div><NavLink to='/'>Back to Properties list</NavLink></div> }
            />
            <Route
              path="/propertys/:propertyId"
              render={ props => <PropertyDetailsLoader id={props.match.params.propertyid}/> }
            />
          </Grid.Column>
        </Grid>
      </Router>
      
    );
  }
}

export default withAuthenticator(App, {includeGreetings: true});

任何帮助都很棒,

0 个答案:

没有答案