Взаимодействие с Apollo GraphQL Store не работает - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь изучить GraphQL, разрабатывая простое приложение со списком дел с использованием React для FrontEnd с Material-UI. Теперь мне нужно обновить информацию о веб-приложении в режиме реального времени после выполнения запроса. Я написал код для обновления магазина, но по какой-то причине он не работает. Это код для App.js.

const TodosQuery = gql`{
  todos {
    id
    text
    complete
  }
}`;

const UpdateMutation = gql`mutation($id: ID!, $complete: Boolean!) {
  updateTodo(id: $id, complete: $complete)
}`;

const RemoveMutation = gql`mutation($id: ID!) {
  removeTodo(id: $id)
}`;

const CreateMutation = gql`mutation($text: String!) {
  createTodo(text: $text) {
    id
    text
    complete
  }
}`;

class App extends Component {
  updateTodo = async todo => {
    await this.props.updateTodo({
      variables: {
        id: todo.id,
        complete: !todo.complete,
      },
      update: (store) => {
        const data = store.readQuery({ query: TodosQuery });
        data.todos = data.todos.map(existingTodo => existingTodo.id === todo.id ? {
          ...todo,
          complete: !todo.complete,
        } : existingTodo);
        store.writeQuery({ query: TodosQuery, data })
      }
    });
  };
  
  removeTodo = async todo => {
    await this.props.removeTodo({
      variables: {
        id: todo.id,
      },
      update: (store) => {
        const data = store.readQuery({ query: TodosQuery });
        data.todos = data.todos.filter(existingTodo => existingTodo.id !== todo.id);
        store.writeQuery({ query: TodosQuery, data })
      }
    });
  };

  createTodo = async (text) => {
    await this.props.createTodo({
      variables: {
        text,
      },
      update: (store, { data: { createTodo } }) => {
        const data = store.readQuery({ query: TodosQuery });
        data.todos.unshift(createTodo);
        store.writeQuery({ query: TodosQuery, data })
      },
    });
  }

  render() {
    const { data: { loading, error, todos } } = this.props;
    if(loading) return <p>Loading...</p>;
    if(error) return <p>Error...</p>;

    return(
      <div style={{ display: 'flex' }}>
        <div style={{ margin: 'auto', width: 400 }}>
          <Paper elevation={3}>
            <Form submit={this.createTodo} />
            <List>
              {todos.map(todo => 
                <ListItem key={todo.id} role={undefined} dense button onClick={() => this.updateTodo(todo)}>
                  <ListItemIcon>
                    <Checkbox checked={todo.complete} tabIndex={-1} disableRipple />
                  </ListItemIcon>
                  <ListItemText primary={todo.text} />
                  <ListItemSecondaryAction>
                    <IconButton onClick={() => this.removeTodo(todo)}>
                        <CloseIcon />
                    </IconButton>
                  </ListItemSecondaryAction>
                </ListItem>
              )}
            </List>
          </Paper>
        </div>
      </div>
    );
  }
}

export default compose(
  graphql(CreateMutation, { name: 'createTodo' }),
  graphql(UpdateMutation, { name: 'updateTodo' }),
  graphql(RemoveMutation, { name: 'removeTodo' }),
  graphql(TodosQuery)
)(App);

Кроме того, я хочу создать некоторые элементы списка, но они тоже не работают. Я пытаюсь ввести текст в поле ввода в режиме реального времени, используя функцию обработчика handleOnKeyDown() в onKeyDown поля ввода. Я передаю событие e в качестве параметра handleOnKeyDown(e), и когда я console.log(e), он вместо записи введенного текста возвращает странный объект, который мне не нужен. Это код, который обрабатывает действия формы:

export default class Form extends React.Component{
    state = {
        text: '',
    }

    handleChange = (e) => {
        const newText = e.target.value;
        this.setState({
            text: newText,
        });
    };

    handleKeyDown = (e) => {
        console.log(e);
        if(e.key === 'enter') {
            this.props.submit(this.state.text);
            this.setState({ text: '' });
        }
    };

    render() {
        const { text } = this.state;
        return (<TextField onChange={this.handleChange} onKeyDown={this.handleKeyDown} label="To-Do" margin='normal' value={text} fullWidth />);
    }
}

Этот кодовый файл включен в мой App.js.

Я не могу выяснить проблемы. Пожалуйста, помогите.

1 Ответ

0 голосов
/ 21 апреля 2020

Я застрял с подобной проблемой. Для меня это решило замену update на refetchQueries как:

updateTodo = async todo => {
    await this.props.updateTodo({
      variables: {
        id: todo.id,
        complete: !todo.complete
      },
      refetchQueries: [{
        query: TodosQuery,
        variables: {
          id: todo.id,
          complete: !todo.complete
        }
      }]
    });
  };

Для вашей второй проблемы попробуйте использовать заглавные буквы 'e' в 'enter' как 'Enter'. Надеюсь, это поможет!

...