I'm using the Apollo's <Mutation> component like this:
import gql from "graphql-tag";
import { Mutation } from "react-apollo";
const ADD_TODO = gql`
mutation addTodo($type: String!) {
addTodo(type: $type) {
id
type
}
}
`;
const AddTodo = () => {
let input;
return (
<Mutation mutation={ADD_TODO}>
{(addTodo, { data }) => (
<div>
<form
onSubmit={e => {
e.preventDefault();
addTodo({ variables: { type: input.value } });
input.value = "";
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Add Todo</button>
</form>
</div>
)}
</Mutation>
);
};
I get this error:
[eslint] JSX props should not use functions (react/jsx-no-bind)
I think it is complaining about:
onSubmit={e => {
e.preventDefault();
addTodo({ variables: { type: input.value } });
input.value = "";
}}
because is an arrow function.
But it's the default in Apollo React Docs: https://www.apollographql.com/docs/react/essentials/mutations.html.
I asked eslint-plugin-react team how to proceed, here: https://github.com/yannickcr/eslint-plugin-react/issues/1872
Hey @johnunclesam, this is an optimization that isn't always necessary, and doesn't really have anything to do with apollo.
Basically you sometimes want to avoid creating new functions/objects in a render method and passing them to child props because this will force that child to re-render. However, depending on the implementation of that child component and where this happens in your app's tree, it often doesn't matter.
Apollo uses a pattern called "render prop function" which makes it really easy to compose. However, the most straightforward way to use it is with an inline function. I would recommend you disable that eslint warning, and optimize when performance becomes a problem. However, if you really want to keep the rule, you can refactor to something like this:
import gql from "graphql-tag";
import { Mutation } from "react-apollo";
import { Component } from "react";
const ADD_TODO = gql`
mutation addTodo($type: String!) {
addTodo(type: $type) {
id
type
}
}
`;
class AddTodo extends Component {
state = { value: "" };
_onSubmit = e => {
e.preventDefault();
addTodo({ variables: { type: this.state.value } });
this.setState({
value: ""
})
};
_onChange = e => {
this.setState({
value: e.target.value
});
};
_renderProp = (addTodo, { data }) => (
<div>
<form
onSubmit={this._onSubmit}
>
<input
value={this.state.value}
onChange={this._onChange}
/>
<button type="submit">Add Todo</button>
</form>
</div>
);
render () {
return (
<Mutation mutation={ADD_TODO}>
{this._renderProp}
</Mutation>
);
}
};
@mike-marcacci Where does "addTodo" come from in _onSubmit in your example?
Most helpful comment
@mike-marcacci Where does "addTodo" come from in
_onSubmitin your example?