Hooks - rkaku/react-hooks-101 GitHub Wiki

useRef

const App = () => {

  const input = useRef(null)

  return (
    <>
      <input ref={ input }/>
      <button onClick={() => { input.current.focus() }}>
        Focus :)
      </button>
    </>
  )
}

useState

const [state , setState] = useState(props)

const { foo, bar } = state

const [baz, setBaz] = useState(initialState)


const reset = () => { setState(props) }

<button onClick={ () => setState({ ...state, foo: foo + 1 })>+1</button>

<input value={ bar } onChange={ e => setState({ ...state, bar: e.target.value }) />

<input value={ baz } onChange={ e => setBaz({ e.target.value }) />

useEffect

useEffect(() => { console.log(('componentDidMount or componentDidUpdate') })

useEffect(() => { console.log(('componentDidMount') }, [])

useEffect(() => { console.log(('callback for foo') }, [foo])

useReducer

const [state, dispatch] = useReducer(reducer, initialState(), initializeMethod)


dispatch(creator())
function useReducer(reducer, initialState) {
  const [state, setState] = useState(initialState)

  function dispatch(action) {
    const nextState = reducer(state, action)
    setState(nextState)
  }

  return [state, dispatch]
}

useContext

import { createContext } from 'react'

const AppContext = createContext({})

export default AppContext
<AppContext.Provider value={{ state, dispatch }}>


const { state, dispatch } = useContext(AppContext)

Redux with Hooks

import { combineReducers } from 'redux'

import fooReducer from './foo'

export default combineReducers({ fooReducer })
const [state, dispatch] = useReducer(reducer, initialStateObject, initializeMethod)

× state => => =>  state.fooReducer

x initialState = {} or []

initialStateObject = { fooReducer: {} }

initialState = () => {
  return {
    balance: 0
  }
}

useQuery

<ApolloProvider client={ client }>

const { loading, error, data } = 

  useQuery(GraphQL, { variables: QUERY_VARIABLES, pollInterval: 500 })
const { loading, error, data, refetch, networkStatus } = 

  useQuery(GraphQL, { variables: QUERY_VARIABLES, notifyOnNetworkStatusChange: true })


if (networkStatus === 4) return 'Refetching!'

if (loading) return null

if (error) return `Error! ${error}`


<button onClick={() => refetch()}>Refetch!</button>
const [dog, setDog] = useState(null)
const [getDog, { loading, data }] = useLazyQuery(GET_DOG_PHOTO)


if (data && data.dog) setDog(data.dog);


{dog && <img src={dog.displayImage} />}
<button onClick={() => getDog({ variables: { breed: 'bulldog' } })}>

useMutation

let input
const [addTodo, { data }] = useMutation(ADD_TODO);


<form
  onSubmit={event => {
    event.preventDefault()
    addTodo({ variables: { type: input.value } })
    input.value = ''
  }}
>
  <input ref={ node => input = node } />
  <button type="submit">Add Todo</button>
const { loading, error, data } = useQuery(GET_TODOS)
const [updateTodo] = useMutation(UPDATE_TODO)


updateTodo({ variables: { id, type: input.value } })
const [addTodo] = useMutation(
    ADD_TODO,
    {
      update(cache, { data: { addTodo } }) {
        const { todos } = cache.readQuery({ query: GET_TODOS })
        cache.writeQuery({ query: GET_TODOS, data: { todos: todos.concat([addTodo]) } })
      }
    }
const [updateTodo, { loading: mutationLoading, error: mutationError }] = useMutation(UPDATE_TODO)

{ mutationLoading && <p>Loading...</p> }
{ mutationError && <p>Error :( Please try again</p> }
// variables

{ [key: string]: any }

// update

(cache: DataProxy, mutationResult: FetchResult)

// refetchQueries

(mutationResult: FetchResult) => Array<{ query: DocumentNode, variables?: TVariables}>

readFragment

const client = new ApolloClient({
  ...,
  cache: new InMemoryCache({
    ...,
    dataIdFromObject: object => object.id,
  }),
})
const todo = client.readFragment({
  id: '5',
  fragment: gql`
    fragment myTodo on Todo {
      id
      text
      completed
    }
  `,
})

writeFragment

client.writeFragment({
  id: '5',
  fragment: gql`
    fragment myTodo on Todo {
      completed
    }
  `,
  data: { 
    completed: true
  }
})
const query = gql`
  query MyTodoAppQuery {
    todos {
      id
      text
      completed
    }
  }
`

// Get the current to-do list
const data = client.readQuery({ query })

const myNewTodo = {
  id: '6',
  text: 'Start using Apollo Client.',
  completed: false,
  __typename: 'Todo'
}

// Write back to the to-do list and include the new item
client.writeQuery({
  query,
  data: {
    todos: [...data.todos, myNewTodo],
  }
})

fetchMore

const FEED_QUERY = gql`
  query Feed($type: FeedType!, $offset: Int, $limit: Int) {
    currentUser {
      login
    }
    feed(type: $type, offset: $offset, limit: $limit) {
      id
      # ...
    }
  }
`;

const FeedWithData = ({ match }) => (
  <Query
    query={FEED_QUERY}
    variables={{
      type: match.params.type.toUpperCase() || "TOP",
      offset: 0,
      limit: 10
    }}
    fetchPolicy="cache-and-network"
  >
    {({ data, fetchMore }) => (
      <Feed
        entries={data.feed || []}
        onLoadMore={() =>
          fetchMore({
            variables: {
              offset: data.feed.length
            },
            updateQuery: (prev, { fetchMoreResult }) => {
              if (!fetchMoreResult) return prev
              return Object.assign({}, prev, {
                feed: [...prev.feed, ...fetchMoreResult.feed]
              });
            }
          })
        }
      />
    )}
  </Query>
)

@connection

const query = gql`
  query Feed($type: FeedType!, $offset: Int, $limit: Int) {
    feed(type: $type, offset: $offset, limit: $limit) @connection(key: "feed", filter: ["type"]) {
      ...FeedEntry
    }
  }
`


client.writeQuery({
  query: gql`
    query Feed($type: FeedType!) {
      feed(type: $type) @connection(key: "feed", filter: ["type"]) {
        id
      }
    }
  `,
  variables: {
    type: "top",
  },
  data: {
    feed: [],
  },
})

cacheRedirects

query ListView {
  books {
    __typename
    id
    title
    abstract
  }
}


query DetailView {
  book(id: $id) {
    __typename
    id
    title
    abstract
  }
}


const cache = new InMemoryCache({
  cacheRedirects: {
    Query: {
      book: (_, args, { getCacheKey }) =>
        getCacheKey({ __typename: 'Book', id: args.id })
    }
  }
})


cacheRedirects: {
  Query: {
    books: (_, args, { getCacheKey }) =>
      args.ids.map(id =>
        getCacheKey({ __typename: 'Book', id: id }))
  }
}
⚠️ **GitHub.com Fallback** ⚠️