How to render new value of array in react - reactjs

Here I am getting my data from child component and trying to add it into existing array and also I am trying to display it in console using map but the moment I try to to do so I get nothing in console:
import "./App.css";
import Home from "./Components/Home";
import {useState} from 'react';
let App = () => {
let DataList = ["Apple","Banana"];
const newList = (data)=>{
DataList = [...DataList,data];
}
return (
<div>
<Home newList = {newList}/>
{ DataList.map((val)=>(
console.log(val)
))
}
</div>
)
};
export default App;

You need to use React hooks to make it work, then only your component will rerender
import "./App.css";
import Home from "./Components/Home";
import {useState} from 'react';
let App = () => {
const [DataList, setDataList] = useState(["Apple","Banana"]);
const newList = (data)=>{
let temp = [...DataList,data];
setDataList(temp);
}
return (
<div>
<Home newList = {newList}/>
{ DataList.map((val)=>(
console.log(val)
))
}
</div>
)
};
export default App;

You imported this for a reason, use it:
import {useState} from 'react';
React won't detect changes to any random variable you declare. So there's no reason for it to re-render the component in the code you have.
State values are fundamental to React. It's how you persist data across renders, and it's how React knows to re-render any given component. Store your data in state:
const [dataList, setDataList] = useState(["Apple","Banana"]);
And use that setter function to update the state:
const newList = (data)=>{
setDataList([...dataList, data]);
};
When React sees that state was updated, it will queue a re-render of the component (in this case re-invoking the App function internally to the framework) so the new state can be used.

Related

Change state value in context file from child component?

Trying to understand context api, and I understand props are passed down. I am trying to change state of my Context file's value to another number like 50.
Created Context File
import React, { useState, createContext } from "react";
export const PointsContext = createContext();
export const PointsProvider = (props) => {
const [points, setPoints] = useState(0);**<--WANT TO CHANGE THIS**
return <PointsContext.Provider value={points}>{props.children}</PointsContext.Provider>;
};
Wrapped Everything In Provider in App.js
import {PointsProvider } from "./PointsContext";
<PointsProvider>
<ChildComponent>
</PointsProvider>
The "ChildComponent" is Provided Context
import React, { useState, useEffect, useContext } from "react";
import { PointsContext } from "../PointsContext";
const value = useContext(PointsContext);
return(
<Button title="ChangeNumber" onPress={() => Change value to 50 }/>
)
I figured it out, instead of importing
const value = useContext(PointsContext);
import this, which gives access to the setState in the context file. As long as you import this on to any screen you will have access to that useState to change stuff.
const [points, setPoints] = useContext(PointsContext);
the rest might go something like this!
<Button title="ChangeNumber" onPress={() => setPoints(50)}/>
<Text>{points}</Text>
This tutorial helped alot thanks devEd, he is one of my favs!
DevEd Youtube React State

React.js - passing functions between components using Context API - not working

I am trying to pass a function between two components but even though I do not have any errors, the function that I am passing wont show or to be precise it is not working. I have two files and one of them is creating a context while the other is using it (obviously). Now, they are not shown in App.js (which is rendered in index.js, usual stuff) they are in the seperate folder. I am using React Router to show one the pages (News.js).
Here are the files:
NewsContext.js
import React, { useContext, createContext, useState, useEffect } from "react";
export const newsK = React.createContext();
export const NewsContext = (props) => {
const working = () => {
console.log("it is working");
};
return <newsK.Provider value={working}>{props.children}</newsK.Provider>;
};
export default NewsContext;
News.js
import React, { useContext, useState, useEffect } from "react";
import { newsK } from "./NewsContext";
import { NewsContext } from "./NewsContext";
const News = () => {
const data = useContext(newsK);
return (
<NewsContext>
<div>
<button onClick={data}></button>
</div>
</NewsContext>
);
};
export default News;
When i pressed the button, it wont do anything. Any tips?
You're trying to use context outside the NewsContext component
The solution for this will be to create a component that will call useContext inside NewsContext.
I.e.
const WrappedButton = () => {
const data = useContext(newsK)
return <button onClick={data} />
}
And then put it inside the NewsContext:
<NewsContext>
<div>
<WrappedButton />
</div>
</NewsContext>

React Hooks useContext value not updating

I'm updating a username based on a form input from another component. I put a console.log inside the provider component to make sure it's getting updated... it is! But the value never updates on the component receiving this value.
Here is the provider component:
import React, { useState, useContext } from 'react';
export const GetFirstName = React.createContext();
export const GetLastName = React.createContext();
export const SetUserName = React.createContext();
export const UserNameProvider = ({ children }) => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
console.log(firstName);
return (
<SetUserName.Provider value={{ setFirstName, setLastName }}>
<GetFirstName.Provider value={firstName}>
<GetLastName.Provider value={lastName}>
{children}
</GetLastName.Provider>
</GetFirstName.Provider>
</SetUserName.Provider>
);
};
Account page (wraps the component with the provider so it can receive context):
import React, { useContext } from 'react';
import { useHistory } from 'react-router-dom';
import { GetLoggedIn, UserNameProvider } from '../Providers/providers.js';
import AccountHeader from './Account/AccountHeader.js';
import AccountItemsList from './Account/AccountItemsList.js';
import LoginModal from './Modal/LoginModal.js';
const Account = () => {
const history = useHistory();
const loggedIn = useContext(GetLoggedIn);
return !loggedIn ? (
<LoginModal closeModal={history.goBack} />
) : (
<div id='account-div'>
<UserNameProvider>
<AccountHeader />
</UserNameProvider>
<AccountItemsList /> // within AccountItemsList,
// another component is wrapped the same way
// to use setFirstName and setLastName
// this works fine, as the console.log shows
</div>
);
};
export default Account;
And finally the AccountHeader page, which receives only the initial value of '', then never reflects the current value after another component calls setFirstName.
import React, { useContext } from 'react';
import { GetFirstName } from '../../Providers/providers.js';
const AccountHeader = () => {
const firstName = useContext(GetFirstName);
return (
<div id='account-top'>
<img src='#' alt='User' />
<h1>{firstName}</h1>
</div>
);
};
Just to check my sanity I implemented a really simple version of this in a codepen and it works as it should. Elsewhere in my app I'm using context to check if the user is logged in. That is also working as it should. I've pulled almost all the hair out of my head.

Context is not available right after page refresh in React

There's WarriorPage component which use context where is data I want to render. After page refresh, firstly I got an empty array from the context and only after a while I got array with my data. That causes error because I'm destructuring object from that array(which is empty in the start). Any sugestions?
WarriorPage
import React, { useContext } from 'react';
import { useParams } from 'react-router-dom';
import AllWarriorsContext from '../../contexts/AllWariorsContext';
export default function WarriorPage() {
let { identy } = useParams();
const { warriorsData } = useContext(AllWarriorsContext);
const {number, name, skill, description} = warriorsData[identy]; // got undefined here after page reload
return(...);
}
In Parent component
import React, { useEffect, useState, useContext } from 'react';
import AllWarriorsContext from '../../contexts/AllWariorsContext';
import WarriorPage from '../WarriorPage/WarriorPage';
export default function Parent() {
const [myWarriorsListContext, setMyWarriorsListContext] = useState([]);
useEffect( () => {
setMyWarriorsListContext(JSON.parse(localStorage.getItem('myWarriorsList')) || []);
},[]);
return(
<AllWarriorsContext.Provider value={{
warriorsData: allWarriorsData
}}>
<WarriorPage />
</AllWarriorsContext>
);
}

reactjs data mapping, get data from server

I'm new reactjs
I'm trying to save data that I got from server like object(array) but I can't.
at render() function, what should I do to save data, I don't wanna display, just save to users (array) or something? I think that I should use "map" but I don't know how to do.
Next, I wanna save users to model.data like this. help me.
Since you just started using react, try using React Hooks instead of class style components. It's the recommended way.
If you just want to store the data without displaying anything you need somekind of a encapsulated/shared state. For example redux or context can help you with that. Since context is in-built and easier to use, here is an example:
First create a context
users-context.js
import React from "react";
export const UsersContext= React.createContext();
Now create a custom hook to store your state.
useUsers.js
import React, {useState, useEffect} from "react";
export const useUsers = () => {
const [users, setUsers] = useState([]);
const getUsers = () =>{
//your fetch
}
useEffect(()=>{ //equivalent to componentDidMount
getUsers();
}, [])
return {users, setUsers}
}
Then provide the context so every component in your app has access to that context.
App.jsx
import {UsersContext} from "./UsersContext";
const App = () => {
const contextValue = useUsers();
return (
<div className={'App'}>
<UsersContext.Provider value={contextValue}>
<Main/>
</UsersContext.Provider>
</div>
);
};
export default App;
If you want to use the state in a component, e.g. a profile page do this:
profile-page.jsx
import React, {useContext} from "react";
import {UsersContext} from "./UsersContext";
const ProfilePage = () => {
const {users} = useContext(UsersContext);
// now you can use it like
console.log(users)
return (...)
}
import { UsersContext } from './Components/usersData/users-context';
const getUsers = () => {
const {users} = UsersContext(UsersContext);
console.log(users);
return users;
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data:[]
}
data.push(getUsers);`
}
}

Resources