Best way to write onClick multiline function? - reactjs

I have this onClick function that shows the details of the user and then sets another state back to true. Would it be better to declare this function outside of the return as it is multiline? and if so how should I write it?
<Button onClick ={() => {setSelectedUser(user); setShowUser(true);}}>{user.name}</Button>
Here the rest of my code as reference:
const UserList = () => {
const [users, setUsers] = useState([])
const [selectedUser, setSelectedUser] = useState()
const [showUser, setShowUser] = useState(true)
const onHandleClick = () => setShowUser(false)
useEffect(() => {
fetch(URL)
.then(res => res.json())
.then(json => setUsers(json));
}, [])
return (
<>
<Header>
<h1>Contact list</h1>
</Header>
<Container>
<div>
{users.map(user => (
<div key={user.id}>
<Button onClick ={() => {setSelectedUser(user); setShowUser(true);}}>{user.name}</Button>
</div>
))}
</div>
{selectedUser && (
<>
{showUser ?
<UserDetail
name={selectedUser.name}
username={selectedUser.username}
email={selectedUser.email}
address={selectedUser.address.street}
phone={selectedUser.phone}
company={selectedUser.company.name}
onClick={onHandleClick}
/>
: false}
</>
)}
</Container>
</>
)
}

If you want to declare function outside of the JSX then you can do as:
<Button onClick={() => changeUser(user)}>{user.name}</Button>
Declaration of function
function changeUser(user) {
setSelectedUser(user);
setShowUser(true);
}

Related

How to show only the selected item in the modal

I am quite new to modals on react. I have 2 questions:
I am trying to show more details onclick the particular gif
what type of test can I write for the async/await response(I have never written a test before)
Further details:
react version: 18
async function handleSubmit(event) {
event.preventDefault();
await axios.get(`https://api.giphy.com/v1/gifs/search?q=${gifname}&api_key=3ZT8IGYuq0IQP1v19SAGm1RNkL5L5FUI`)
.then((response) => {
let resp = response.data.data
setgif(resp)
})
};
useEffect (() => {
handleSubmit()}, []
)
function GifList(props) {
const gif_use = props.gif;
const [modalIsOpen, setModalIsOpen] = useState(false);
return (
<>
<div className="img_div row">
{
gif_use.map((gif_use1, i) =>
<img className="col-lg-4" src={gif_use1.images.downsized.url}
alt='gif-result'
onClick={
() => setModalIsOpen(true)
}
key={i}/>
)}
</div>
<Modal isOpen={modalIsOpen} onRequestClose={
() => setModalIsOpen(false)
}>
{
gif_use.map((gif_use1, i) =>
<img className="col-lg-4" src={gif_use1.images.downsized.url}
alt='gif-result'
onClick={
() => setModalIsOpen(true)
}
key={i}/>
)}
<button onClick={
() => setModalIsOpen(false)
}>close</button>
</Modal>
</>
);
}

Fetching data on second click problem! React js Next js

When I click on the search button the first time API response is "undefined" (based on what console.log says) but the second time it has the response from API.
Why does this happen?
xport default function Home() {
const [searchTerm, setSearchTerm] = useState('');
const fetcher = (url) => fetch(url).then((res) => res.json());
const [shouldFetch, setShouldFetch] = useState(false);
const { data, error } = useSWR(
() =>
shouldFetch
? `https://eu-central-1.aws.webhooks.mongodb-realm.com/api/client/v2.0/app/lottigully-jjrda/service/movies/incoming_webhook/movies?arg=${searchTerm}`
: null,
fetcher
);
if (error) return 'An error has occurred.';
return (
<>
<main>
<div className={style.main_container}>
<NavBar />
<Hero />
</div>
<div className={style.search_container}>
<SearchBar
onChange={(e) => {
setSearchTerm(e.target.value);
}}
/>
<button
onClick={() => {
setShouldFetch(true);
console.log(searchTerm);
console.log(data);
}}
>
Search!
</button>
</div>
</main>
</>
);
}

On click of button not filtering array like intended

Can someone explain to me why the filter method isn't working as intended? I am trying to update my array of objects with filtered results based on the first name.
export default function App() {
const { data } = useDataFetcher();
const searchArray = data;
const [inputField, setInputField] = useState("");
const searchUser = () => {
searchArray.filter((el) => el.firstName.includes(inputField));
};
useEffect(() => {
searchUser();
}, [inputField]);
return (
<div className="App">
<h1>Xaxis Frontend Interview</h1>
<input onChange={(e) => setInputField(e.target.value)} />
<button onClick={(e) => searchUser()}> Search </button>
{searchArray.map((userData, i) => (
<Users
key={i}
firstName={userData.firstName}
lastName={userData.lastName}
email={userData.email}
bio={userData.bio}
/>
))}
</div>
);
}
You need to create a state which will contain the list of the users. Then, you want to update this state when inputField state changes.
export default function App() {
const { data } = useDataFetcher();
const searchArray = data;
const [users, setUsers] = useState([])
const [inputField, setInputField] = useState("");
useEffect(() => {
setUsers(data);
}, [data]);
useEffect(() => {
const filteredArray = users.filter((el) => el.firstName.includes(inputField));
setUsers(filteredArray)
}, [inputField]);
return (
<div className="App">
<h1>Xaxis Frontend Interview</h1>
<input onChange={(e) => setInputField(e.target.value)} />
{users.map((userData, i) => (
<Users
key={i}
firstName={userData.firstName}
lastName={userData.lastName}
email={userData.email}
bio={userData.bio}
/>
))}
</div>
);
}
Or if you want to update the list of users by clicking a button:
export default function App() {
const { data } = useDataFetcher();
const searchArray = data;
const [users, setUsers] = useState([])
const [inputField, setInputField] = useState("");
useEffect(() => {
setUsers(data);
}, [data]);
const searchUser = () => {
const filteredArray = users.filter((el) => el.firstName.includes(inputField));
setUsers(filteredArray)
};
return (
<div className="App">
<h1>Xaxis Frontend Interview</h1>
<input onChange={(e) => setInputField(e.target.value)} />
<button onClick={() => searchUser()}> Search </button>
{users.map((userData, i) => (
<Users
key={i}
firstName={userData.firstName}
lastName={userData.lastName}
email={userData.email}
bio={userData.bio}
/>
))}
</div>
);
}

React - TypeError: setActiveProject is not a function

I'm passing a setter function for a state down to a component and am getting the above error saying the setter is not a function.
App.js
const App = () => {
const [activeProject, setActiveProject] = useState();
return (
<div className="app-container">
<ProjectList
activeProject={activeProject}
setactiveProject={setActiveProject}
/>
</div>
);
};
ProjectList.js
const ProjectList = ({ activeProject, setActiveProject }) => {
const [projectList, setprojectList] = useState([]);
useEffect(() => {
axios.get('http://localhost:1337/api/projects').then((allProjects) => {
setprojectList(allProjects.data);
});
}, []);
return (
<ThemeProvider theme={THEME}>
<div className="projectlist">
{projectList.map((project) => (
<Button
variant="outlined"
value={project.name}
key={project._id}
onClick={(e) => setActiveProject(e.target.value)}
>
{project.name}
</Button>
))}
</div>
</ThemeProvider>
);
};
You are passing the prop setactiveProject instead of setActiveProject in App.js
const App = () => {
const [activeProject, setActiveProject] = useState();
return (
<div className="app-container">
<ProjectList
activeProject={activeProject}
setactiveProject={setActiveProject} // <- here
/>
</div>
);
};

re render on state change with useEffect

App won't re render different data on state change.
State does change in the dev tools but doesn't show on page.
Using button to filter.
export const StoriesPage = () => {
const [storyIds, setStoryIds] = useState([]);
const [storyUrl, setStoryUrl] = useState('top');
useEffect(() => {
let url = baseUrl;
storyUrl === 'top'
? (url += 'topstories.json')
: (url += 'newstories.json');
getStoryIds(url).then(data => setStoryIds(data));
}, [storyUrl]);
return (
<div>
<div>
<button onClick={() => setStoryUrl('new')}>New</button>
<button onClick={() => setStoryUrl('top')}>Top</button>
</div>
{storyIds.map((storyId, index) => (
<Story key={index} storyId={storyId} />
))}
</div>
);
};
Added a function that clears storyIds before setStoryUrl
const handleFilter = tag => {
setStoryIds([]);
setStoryUrl(tag);
};

Resources