React-Redux with functional Components
Concisely merging objects can be done with spread syntax instead of Object.assign. The ADD_USER case can use:
return { ...state, user: action.user };

Using spread syntax instead of Object.assign doesn't have a big impact here, but it makes things so much easier when the state structure grows to be large and complicated.
Functional programming does not reassign variables - everything should be declared with const. If you want to be more functional, change addUser to use the conditional operator to either assign the empty string or the extractUser result to the user variable:
export const addUser = (resp) =&gt; {
  const user = validResp(resp) ? extractUser(resp) : &quot;&quot;;
  return {
    type: &quot;ADD_USER&quot;,
    user
  };
};

(Note that if the key is named the same as the variable the value is in, you can use shorthand property names like above. You could also return the whole object at once without declaring a user variable first.)
useEffect bug Since you didn't provide a dependency array to useEffect, its callback will run on every render. I'm pretty sure this isn't desirable - you want it to run only on the initial render, right? Pass an empty dependency array to useEffect so that the callback inside only runs on mount:
useEffect(() =&gt; {
  axios.get(url).then((resp) =&gt; dispatch(addUser(resp)));
}, []);

Error handling If the axios.get Promise rejects, no indication is given. Always .catch Promises somewhere. You might want something like
useEffect(() =&gt; {
  axios.get(url)
    .then((resp) =&gt; dispatch(addUser(resp)))
    .catch((error) =&gt; dispatch(addError(error.message)));
}, []);

or something of the sort, to show that an error occurred.