React js export a variable - reactjs

I want to receive a value from my variable(meta) in the file form.js
this one:
export const TextInput = ({ icon, ...props }) => {
const [field, meta] = useField(props);
const [showpass, setShowpass] = useState(false);
const [showPopup, setShowPopup] = useState(false);
{'....'}
And I wanto to send it to the file login.js
// styled components
import {
StyledTextInput,
StyledFormArea,
StyledFormButton,
StyledLabel,
Avatar,
StyledTitle,
colors,
ButtonGroup,
ExtraText,
TextLink,
CopyrightText,
ErrorMsg
} from "../components/Styles";
import Logo from "./../assets/logo.png";
// formik
import { Formik, Form,useField } from "formik";
import {TextInput} from "../components/FormLib";
import * as Yup from "yup";
//icons
import { FiMail, FiLock } from "react-icons/fi";
// Loader
import Loader from "react-loader-spinner";
// auth & redux
import { connect } from "react-redux";
import { loginUser } from "../auth/actions/userActions";
import { useHistory } from "react-router-dom";
import AuthCode from 'react-auth-code-input';
import React, { useState } from 'react';
//pop up style.css
import '../assets/css/popup.css'
// Import popup lib
import Popup from "reactjs-popup";
import 'reactjs-popup/dist/index.css';
const Login = ({ loginUser}) => {
const history = useHistory();
const [showPopup, setShowPopup] = useState(false);
{......}
I know it may be a begginner question, but im not being able to figure out how to send this variable through files , by now thanks for the support
Some part of the login file where i want to check the variable
useEffect(() => {
if(meta.error === 'codigo 2 fatores incorreto'){
setShowPopup(true);
}
}, [meta.error])
As you can see I want to handle an pop up in the page login , but I need to get the meta variable to do this

you can create the onMetaChange property then use useEffect hook to pass the meta to the login form whenever meta is changed
like below
export const TextInput = ({onMetaChange, ...props}) => {
const [field, meta] = useField()
...
useEffect(() => {
onMetaChange && onMetaChange(meta);
}, [meta])
...
}
also note that this is not the best practice for doing this you can check code samples from the library you are using to find out what is the best practice and best style

Related

From my shopit project, the browser is not rendering the ProductDetails page

I'm not sure whether it is a problem to do with react-router version or what? Ive tried installing react v6 from v5 but the the productDetails page is just plain white
here is the ProductDetails.js
import Loader from '../layouts/Loader'
import MetaData from '../layouts/MetaData'
import { useAlert } from 'react-alert'
import { useDispatch, useSelector } from 'react-redux'
import { getProductDetails, clearErrors } from '../../actions/productActions'
import { useParams } from 'react-router-dom'
const ProductDetails = () => {
const dispatch = useDispatch();
const alert = useAlert();
const params = useParams()
const { loading, error, product } = useSelector(state => state.ProductDetails)
useEffect(() => {
dispatch(getProductDetails(params.id))
if(error) {
alert.error(error);
dispatch(clearErrors())
}
}, [dispatch, alert, error, params.id])
</Fragment>
)}
</Fragment>
)
}
export default ProductDetails```
After installing v6 of react-router, using the attribute match did not work as the console's output was match is not defined so i used params instead...the end result is a blank and plain white browser page.

react context not working when provider placed at certain parts of the element tree

I'm using a react context to manage a large input form, and I want the provider to be placed just around that input form. But it throws the following error: "A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it." This is my context:
import React from "react";
import { useState } from "react";
const AddHeaderContext = React.createContext({
headerType: "",
})
export const AddHeaderContextProvider = (props) => {
const [headerType, setHeaderType] = useState("noimage")
const headerTypeChangeHandler = (type) => {
setHeaderType(type)
}
const contextValue = {
headerType: headerType,
}
return (
<AddHeaderContext.Provider value={contextValue}>
{props.children}
</AddHeaderContext.Provider>
)
}
export default AddHeaderContext
This is when there is an error:
import AddHeaderContextProvider from './store/AddHeaderContext'
<AddHeaderContextProvider>
<AddHeaderSection />
</AddHeaderContextProvider>
But weirdly the error disappears when I move the context up into my index.js top level element and wrap everything in it.
Any idea why that could be? Also, I tap into this context usinig "useContext" hooks and not .Consumer.
I figured it out:
I just needed to use curly brackets around the contextProvider since it wasn't the main export from that file:
import { AddHeaderContextProvider } from './store/AddHeaderContext'
<AddHeaderContextProvider>
<AddHeaderSection />
</AddHeaderContextProvider>
You have this export default AddHeaderContext in AddHeaderContext.js, so when you do import AddHeaderContextProvider from './store/AddHeaderContext'
you are actually getting AddHeaderContext (the default export), not AddHeaderContextProvider.
Either change your import to import {AddHeaderContextProvider} from './store/AddHeaderContext' or your exports as below:
import React from "react";
import { useState } from "react";
export const AddHeaderContext = React.createContext({
headerType: "",
});
const AddHeaderContextProvider = (props) => {
const [headerType, setHeaderType] = useState("noimage");
const headerTypeChangeHandler = (type) => {
setHeaderType(type);
};
const contextValue = {
headerType: headerType,
};
return (
<AddHeaderContext.Provider value={contextValue}>{props.children}</AddHeaderContext.Provider>
);
};
export default AddHeaderContextProvider;

Getting "TypeError: render is not a function" error when i import context from another file

I am trying to do react context on a function. Initially, I created react context in the same file as the provider, but then I got a warning on the console saying that I should put context in a separate file, but when I do that, for some bizarre reason, I get an error, even though I am pretty much doing the exact same thing, what am I doing wrong? I am only showing the relevant bits of the code.
The following code below works fine
import * as React from 'react';
import {
BrowserRouter as Router,
NavLink,
Switch,
Route,
} from 'react-router-dom';
import Header from './header.js';
import './OldApp.css';
import { useState, useEffect } from 'react';
//Context import commented
//import UserObjAndDbProvider from './dbAndUserObjContext';
import routes from './routes';
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
const Context = React.createContext();
export const UserObjAndDbProvider = Context.Provider;
export const UserObjAndDbConsumer = Context.Consumer;
const App = ({ user, database }) => {
var [membership, setMembership] = useState(false);
const docRef = database.collection("userCollection").doc(`${user.uid}`)
//get data
const FindOutMembership = async () => {
var booleanVal = null;
docRef.get().then(function(doc) {
if (doc.exists) {
const booleanVal = doc.data().membership;
setMembership(membership = booleanVal);
} else {
console.log("Error: no such document exists")
}
})
}
useEffect(() => {
FindOutMembership();
})
return (
<UserObjAndDbProvider value={'i am sexy and i like it'}>
<Router>
//some routing stuff done here
</Router>
</UserObjAndDbProvider>
);
};
export default App;
but when i take context stuff out, and put in in another file(which is in the same folder) and import it i get a weird error titled "TypeError: render is not a function"
import * as React from 'react';
import {
BrowserRouter as Router,
NavLink,
Switch,
Route,
} from 'react-router-dom';
import Header from './header.js';
import './OldApp.css';
import { useState, useEffect } from 'react';
//Context import now uncomment
import UserObjAndDbProvider from './dbAndUserObjContext';
import routes from './routes';
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import { useContext, createContext } from 'react';
const App = ({ user, database }) => {
var [membership, setMembership] = useState(false);
const docRef = database.collection("userCollection").doc(`${user.uid}`)
const FindOutMembership = async () => {
var booleanVal = null;
docRef.get().then(function(doc) {
if (doc.exists) {
const booleanVal = doc.data().membership;
setMembership(membership = booleanVal);
} else {
console.log("Error: no such document exists")
}
})
}
useEffect(() => {
FindOutMembership();
})
//console.log(membership);
return (
<UserObjAndDbProvider value={'i am sexy and i like it'}>
<Router>
//some routing stuff done here
</Router>
</UserObjAndDbProvider>
);
};
export default App;
my context file is called dbAndUserObjContext.js and looks like this
import React from 'react'
import { createContext } from 'react';
const Context = React.createContext();
export const UserObjAndDbProvider = Context.Provider;
export const UserObjAndDbConsumer = Context.Consumer;
export default Context;

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>
);
}

createContext using a dynamic object

1. Static object
To create context based on a static object, I use this code:
import React, { createContext } from 'react';
const user = {uid: '27384nfaskjnb2i4uf'};
const UserContext = createContext(user);
export default UserContext;
This code works fine.
2. Dynamic object
But if I need to create context after fetching data, I use this code:
import React, { createContext } from 'react';
const UserContext = () => {
// Let's suppose I fetched data and got user object
const user = {uid: '18937829FJnfmJjoE'};
// Creating context
const context = createContext(user);
// Returning context
return context;
}
export default UserContext;
Problem
When I debugg option 1, console.log(user) returns the object. Instead, option 2, console.log(user) returns undefined. What I'm missing?
import React, { useEffect, useState, useContext } from 'react';
import UserContext from './UserContext';
const ProjectSelector = (props) => {
const user = useContext(UserContext);
console.log(user);
return(...);
}
export default App;
one thing i would suggest is move this logic to a react component itself.
anhow you need to use a Provider in which you will set value to be the value consumers need to consume.useEffect is greatway to do asynchronous updates, like your requirment.
so , use a state variable as value of provider.in useEffect you fetch the data and update the state variable which in turn will update context value.
following is the code
UserContext.js
import { createContext } from "react";
const UserContext = createContext();
export default UserContext;
App.js
export default function App() {
const [user, setUser] = useState();
useEffect(() => {
console.log("here");
fetch("https://reqres.in/api/users/2")
.then(response => {
return response.json();
})
.then(data => {
setUser(data);
});
}, []);
return (
<div className="App">
<UserContext.Provider value={user}>
<DummyConsumer />
</UserContext.Provider>
</div>
);
}
DummyConsumer.js
import React, { useContext } from "react";
import UserContext from "./UserContext";
const DummyConsumer = () => {
const dataFromContext = useContext(UserContext);
return <div>{JSON.stringify(dataFromContext)}</div>;
};
export default DummyConsumer;
demo:anychronus context value providing

Resources