I'm using the material-ui library's component Autocomplete with React flux to create a Search Bar that finds users.
I want every option to be a link to a page with more information of that user. Currently, it only works the first time I click on an option. Every time after that it changes the URL but the page is not re-rendered.
This is the Autocomplete code:
export function SearchBar() {
const [url, setUrl] = useState("/perfil/");
const { store, actions } = useContext(Context);
useEffect(() => {
actions.search();
}, [url]);
const artistas = store.artistas.slice();
return (
<Autocomplete
id="autocomplete"
freeSolo
disableClearable
options={artistas}
getOptionLabel={(option) => option.nombre " " option.apellido}
renderOption={(option) => (
<Link
className="text-black text-decoration-none"
onClick={() => setUrl(url option.id)}
to={`/perfil/${option.id}`}
>
{option.nombre} {option.apellido}
</Link>
)}
renderInput={(params) => (
<TextField
{...params}
size="small"
placeholder="Search for your artist"
margin="normal"
variant="outlined"
InputProps={{ ...params.InputProps, type: "search" }}
/>
)}
/>
);
}
This is the page where it is redirected:
export const Perfil = () => {
const { user_id } = useParams();
return (
<>
<About user_id={user_id} />
<Galeria user_id={user_id} />
</>
);
};
The flux action is this:
search: async () => {
try {
const response = await fetch(
process.env.BACKEND_URL "/api/artistas"
);
const data = await response.json();
setStore({
artistas: data,
});
} catch (error) {
console.log("Error loading message from /api/artistas", error);
}
}
At last, this is the layout page:
return (
<div>
<BrowserRouter basename={basename}>
<ScrollToTop>
<Navbar />
<Routes>
<Route element={<Inicio />} path="/" />
<Route element={<Login />} path="/login" />
<Route element={<Registro />} path="/registro" />
<Route element={<Perfil />} path="/perfil/:user_id" />
<Route element={<Producto />} path="/producto/:theid" />
<Route
element={<ConfiguracionUsuario />}
path="/configuracion/:theid"
/>
<Route element={<h1> Not found! </h1>} />
</Routes>{" "}
<Footer />
</ScrollToTop>{" "}
</BrowserRouter>{" "}
</div>
);
CodePudding user response:
Link tags work first move to url. After that onClick logic will start after moved link. So if you want to use Link tag with onClick then i recommend two ways.
- react-router-dom v5 or lower : just don't use 'to' property and just use onClick and in the onClick property you can use useHistory hook inside onClick. You can use under 2. Option here too.
- react-router-dom v6 or lower : use 'a' tag with onClick property you can use useNavigate hook inside onClick.
CodePudding user response:
I fixed it. The problem was in the Galeria component. It took the id by props:
useEffect(() => {
actions.producto_galeria(props.user_id);
}, []);
But we should have used a stored variable with the ID that changes on every click with a flux action, instead of props. So now, I get the ID as follows:
flux new action:
get_artista_id: (artista_id) => {
setStore({ artista_id: artista_id });
}
Link new onClick:
<Link
className="text-black text-decoration-none"
onClick={() => {
actions.get_artista_id(option.id);
}}
to={`/perfil/${option.id}`}
>
{option.nombre} {option.apellido}
</Link>
useEffect on Galeria to detect the change on the ID:
useEffect(() => {
actions.producto_galeria(store.artista_id);
}, [store.artista_id]);