rumon
rumon

Reputation: 614

Value of React input component cannot be changed if "value" field is used

I'm using material-UI for my React app.

I want to delete value inserted to input field by clicking another component.

The issue is that the OutlinedInput field works properly only when it does not have value property. In case it is added, the value from value is shown inside the OutlinedInput field and no another value can be inserted. However, I cannot delete the value of OutlinedInput by clicking another React component if OutlinedInput doesn't have value property.

const Search = (props: any) => {
  const searchedMovie = useSelector(
    (state: RootState) => state.searchedMovie
  );
  const isMovieOpened = useSelector(
    (state: RootState) => state.isMoviePageOpened
  );
  const dispatch: Dispatch<any> = useDispatch();
  let history = useHistory();
  
  const fetchMoviesList = (event: any) => {
    const searchedMovieValue = event.target.value;
    dispatch(changeSearchedMovie(searchedMovieValue));
    window.scrollTo(0, 0);

    if (isMovieOpened === true) {
      dispatch(isMoviePageOpened(false));
      history.push("/");
    }
  }

  const handleKeyPress = (event: any) => {
    if (event.keyCode === 13) {
      fetchMoviesList(event);
    }
  }

  useEffect(()=>{
    if (searchedMovie) {
      fetchSearchedMovie(searchedMovie)
        .then((res) => dispatch(addHomePageMovies(res)))
        .catch(() => dispatch(addHomePageMovies([])));
    } else {
      fetchMovies('1')
        .then((res) => dispatch(addHomePageMovies(res)))
        .catch(() => dispatch(addHomePageMovies([])));
    }
     // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchedMovie]);
  
  return (
    <>
      <OutlinedInput 
          color="secondary" 
          className="seach-field" 
          type="string"  
          onBlur={fetchMoviesList} 
          onKeyDown={handleKeyPress}
          placeholder="Search" 
          />
    </>
  );
}

export default Search;

How can I solve it? Thanks!

Upvotes: 1

Views: 843

Answers (1)

Mack
Mack

Reputation: 771

Generally, input components in react can follow two patterns: controlled components or uncontrolled components.

In a controlled component, the parent stores the current value as state and provides it via a prop to the input component. It also provides an onChange handler to update the state on the parent whenever the value changes from the child.

In an uncontrolled component, the state is managed internally by the component.

Many components (including material UI's) offer the ability to be either controlled or uncontrolled, by allowing you to pass both or neither of value/onChange. Your current solution is a mix of both, which is a mistake.

You should add a useState hook to the Search component to store the input value (a string) and pass it to the OutlinedInput. You should also pass an onChange callback which sets this state to event.target.value.

Upvotes: 1

Related Questions