I am following the WhatsApp clone on YouTube, I did exactly what they were doing but I don't know why I'm getting this error. I was
I read a lot of blogs, but I couldn't resolve it.
In app, it gives this error and couldn't dismiss.
./src/App.js Line 10: 'dispatch' is assigned a value but never used no-unused-vars
In login, it gives this error.
./src/Login.js Line 9: Unexpected empty object pattern no-empty-pattern
<!-- begin snippet: js hide: false console: true babel: false -->
import React from "react";
import "./Login.css";
import { Button } from "#mui/material";
import { auth, provider } from "./firebase";
import { useStateValue } from "./StateProvider";
import { actionTypes } from "./reducer";
function Login() {
const [value, dispatch] = useStateValue({});
// const [value, dispatch] = useStateValue({})
// const [{ type, user }, dispatch] = useStateValue();
const signIn = () => {
auth
.signInWithPopup(provider)
.then((result) => {
dispatch({
type: actionTypes.SET_USER,
user: result.user,
});
})
.catch((error) => alert(error.message));
};
return (
<div className="login">
<div className="login__container">
<img
src="https://www.freepnglogos.com/uploads/whatsapp-logo-png-hd-2.png"
alt=""
/>
<div className="login__text">
<h1>Sign in to WhatsApp</h1>
</div>
<Button onClick={signIn}>Sign In with Google</Button>
</div>
</div>
);
}
export default Login;
import React from "react";
import "./App.css";
import Sidebar from "./Sidebar";
import Chat from "./Chat";
import Login from "./Login";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { useStateValue } from "./StateProvider";
function App() {
const [{ user }, dispatch] = useStateValue();
return (
<div className="app">
{!user ? (
<Login />
) : (
<div className="app__body">
<Router>
<Sidebar />
<Routes>
<Route path="/rooms/:roomId" element={<Chat />} />
<Route path="/" element={<Chat />} />
</Routes>
</Router>
</div>
)}
</div>
);
}
export default App;
import React, { createContext, useContext, useReducer } from "react";
export const StateContext = createContext();
export const StateProvider = ({ reducer, initialState, children }) => (
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
);
export const useStateValue = () => useContext(StateContext);
export const initialState = {
user: null,
};
export const actionTypes = {
SET_USER: "SET_USER",
};
const reducer = (state, action) => {
console.log(action);
switch (action.type) {
case actionTypes.SET_USER:
return {
...state,
user: action.user,
};
default:
return state;
}
};
export default reducer;
Related
Page not rendering after adding if statement and useSelector hook.
Here is my App component:
import React from 'react';
import Sidebar from "./Sidebar"
import Feed from "./Feed"
import { useSelector } from "react-redux";
import { selectUser } from "./features/userSlice";
import Login from "./Login";
import './App.css';
import Header from './Header';
function App() {
const user = useSelector(selectUser);
return (
<div className="app">
<Header />
{!user
? ( <Login /> )
: (
<div className="app_body">
<Sidebar />
<Feed />
</div>
)
}
{/* Gidgets */}
</div>
);
}
export default App;
The app component quits rendering after I place the app_body inside this if statement and adding both of these :
const user = useSelector(selectUser);
{!user
? ( <Login />)
: (
<div className="app_body">
<Sidebar />
<Feed />
</div>
)
}
Here is my userSlice component if this is relevant:
import { createSlice } from '#reduxjs/toolkit';
const initialState = {
user: null,
status: 'idle',
};
export const userSlice = createSlice({
name: "user",
initialState,
user:null,
reducers: {
login: (state, action) => {
state.value = action.payload;
},
logout: (state) => {
state.user = null;
},
},
});
export const {login, logout} = userSlice.actions;
export const selectUser = (state) => state.user.user;
export default userSlice.reducer;
I tried eliminating different pieces of code and it appears the two pieces of code mentioned caused it to stop rendering.
I just looked in my store component:
import { configureStore } from '#reduxjs/toolkit';
import userReducer from '../features/userSlice';
export const store = configureStore({ reducer: { user: userReducer, }, });
And I had
count:userReducer instead of user: userReducer
That was the issue.
Thank you guys so much for the help!
I am trying to connect the metamask wallet to my react-app. But in the process I am getting a few errors as mentioned below please help.
getWeb3.js
import Web3 from 'web3';
import {useEffect, useState} from 'react';
// Wallet connect code
const useWeb3 = () => {
const [web3,setweb3] = useState(null);
useEffect(() => {
var instance;
if(window.ethereum) {
try{
instance = new Web3(window.ethereum);
}catch(error){
console.error(error);
};
}else if (window.web3) {
instance = new Web3(window.web3);
}else{
const provider = new Web3.provider.HttpProvider('http://127.0.0.1:8545')
instance = new Web3(provider);
}setweb3(instance);
},[]);
return web3;
};
export {useWeb3};
store.js
import React, {useReducer, useContext, createContext} from 'react';
const StoreContext = createContext();
const initialState = {
message: '',
address: null,
balance: 0
};
const reducer = (state, action) => {
switch(action.type){
case "NEW-ADDRESS":
return {
...state,
address: action.newAddress,
message: action.message
}
default:
throw new Error('Unknown type of action ${action.type');
}
};
export const StoreProvider = ({children}) => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<StoreContext.Provider value = {{state, dispatch}}>
{children}
</StoreContext.Provider>
);
};
export const useStore = () => useContext(StoreContext);
storeApi.js
import {useStore} from './store'
const useStoreApi = () => {
const {state, dispatch} = useStore();
return {
address: state.address,
balance: state.balance,
message: state.message,
setBalance: (newBalance) => {
dispatch({
type: "SET-BALANCE",
newBalance
});
},
setAddress: newAddress => {
dispatch({
type: "New-Address",
newAddress,
message: "New account added successfully!"
});
}
};
};
export {useStoreApi};
app.js
import { useStoreApi } from './storeApi';
import { useWeb3 } from './getWeb3';
import logo from './logo.svg';
import './App.css';
import {Button} from '#material-ui/core';
function App() {
const {address,balance,message, setBalance,setAddress} = useStoreApi();
const web3 = useWeb3();
const setUserAccount = async (e) => {
console.log("rhis add");
if(window.ethereum) {
await window.ethereum.enable();
web3.eth.getAccounts().then(accounts => {
setAddress(accounts[0]);
console.log("rhis add");
});
}
};
setUserAccount();
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<code>src/App.js</code>
</p>
{
address ? (
<>
<p> Your add: {address}</p></>
): "s"
}
{/* <Button variant="outlined" color="primary" onClick={() => setUserAccount()}>Conn</Button> */}
{/* <form action="http://localhost:3000/">
<button type="submit" onClick={() => setUserAccount()}>Submit</button>
</form> */}
</header>
</div>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {StoreProvider} from './store';
ReactDOM.render(
<React.StrictMode>
<StoreProvider>
<App />
</StoreProvider>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
Errors:
App.js:16 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'eth')
at setUserAccount (App.js:16)
store.js:20 Uncaught Error: Unknown type of action ${action.type
index.js:1 The above error occurred in the component:
at StoreProvider (http://localhost:3000/static/js/main.chunk.js:847:3)
It looks like you're importing useWeb3 wrong:
const web3 = useWeb3();
But you export it like:
export {useWeb3};
So now you would have to call it like: web3.useWeb3()
Is this code you found at a tutorial somewhere? It's hard to follow...
I'm creating a simple example in react js using createContext and useState, but I'm doing something wrong, look it:
this is my component categoriacontex.js
import { createContext } from "react";
const CategoriaContext = createContext();
export default CategoriaContext;
this's component types.js
export const GET_CATEGORIAS = "GET_CATEGORIAS";
this's component categoriasreducer.js
import { GET_CATEGORIAS } from "../types";
export default (state, action) => {
const { payload, type } = action;
;
switch (type) {
case GET_CATEGORIAS:
return {
...state,
categorias: payload,
};
default:
return state;
}
};
this's component categoriastate.js
import React, { useState } from 'react';
import CategoriaContext from './CategoriaContext';
import CategoriaReducer from './CategoriasReducer';
import Data from '../../Data/Categorias.json';
import { GET_CATEGORIAS } from "../types";
const CategoriaState = (props) => {
const initialState = {
categorias: [],
selectedCategoria: null,
};
const [state, setstate] = useState(CategoriaReducer, initialState);
const GetCategorias = () => {
try {
setstate({ type: GET_CATEGORIAS, payload: Data });
} catch (error) {
console.error(error);
}
};
return(
<CategoriaContext.Provider
value={{
categorias: state.categorias
}}
>
{props.children}
</CategoriaContext.Provider>
)
};
export default CategoriaState;
this one is component app.js
import React, { Component } from 'react';
import './App.css';
import Header from './Component/Header/Header';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import CategoriaState from './Context/Categorias/CategoriaState';
import AddCat from './Component/Categorias/AddCat';
import Allcat from './Component/Categorias/AllCat';
class App extends Component {
render(){
return(
<CategoriaState>
<div className="container">
<Router>
<Header />
<Switch>
<Route exact path="/">
<h1>home</h1>
</Route>
<Route path="/addcat">
<AddCat />
</Route>
<Route path="/allcat">
<Allcat />
</Route>
</Switch>
</Router>
</div>
</CategoriaState>
)
}
}
export default App;
and this's componente allcat.js
import React, { useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useContext } from 'react';
import CategoriaContext from '../../Context/Categorias/CategoriaContext';
const AllCat = () => {
const { categorias, GetCategorias } = useContext( CategoriaContext );
useEffect(() => {
GetCategorias();
},[])
return(
<div className="container mx-auto">
<div className="card col-md-5 mx-auto">
<h4 className="card-title text-center px-0 mx-0 border-bottom">Categorias</h4>
<div className="card-body px-0">
</div>
</div>
</div>
)
};
export default AllCat;
I know that I have some errors, because this is my first example using context in react js, I wan't is create a simple crud using context and hook, I have a file data, this file is call Data, this file have an id, description, idfather.
so please, do you can help me, the better way to work with context and usestate??
In categoriastate.js you don't set the GetCategorias member of the Provider's value, so you will only access the categorias from useContext( CategoriaContext ) and the GetCategorias will be undefined (in allcat.js).
I'm currently struggling with React Context. I'd like to pass functions allowing the show / hide cart logic in the context, instead of using props between components.
I dont understand why when clicking on the button in HeaderCartButton component, it doesn't trigger the **onClick={ctx.onShowCart}** that is in my context, even though when I console log the cartCtx.state it is properly updated, which should then add the component in the App.js
//App.js
import { useContext } from "react";
import Header from "./components/Layout/Header";
import Meals from "./components/Meals/Meals";
import Cart from "./components/Cart/Cart";
import CartProvider from "./store/CartProvider";
import CartContext from "./store/cart-context";
function App() {
const ctx = useContext(CartContext);
return (
<CartProvider>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</CartProvider>
);
}
export default App;
//cart-context.js
import React from "react";
const CartContext = React.createContext({
state: false,
onShowCart: () => {},
onHideCart: () => {},
items: [],
totalAmount: 0,
addItem: (item) => {},
removeItem: (id) => {},
});
export default CartContext;
//CartProvider.js
import CartContext from "./cart-context";
import { useState } from "react";
const CartProvider = (props) => {
const [cartIsShown, setCartIsShown] = useState(false);
const showCartHandler = () => {
setCartIsShown(true);
};
const hideCartHandler = () => {
setCartIsShown(false);
};
const handleAddItem = (item) => {};
const handleRemoveItem = (id) => {};
const cartCtx = {
state: cartIsShown,
onShowCart: showCartHandler,
onHideCart: hideCartHandler,
items: [],
totalAmount: 0,
addItem: handleAddItem,
removeItem: handleRemoveItem,
};
return (
<CartContext.Provider value={cartCtx}>
{props.children}
</CartContext.Provider>
);
};
export default CartProvider;
//Header.js
import { Fragment } from "react";
import HeaderCartButton from "./HeaderCartButton";
import mealsImage from "../../assets/meals.jpg";
import classes from "./Header.module.css";
const Header = (props) => {
return (
<Fragment>
<header className={classes.header}>
<h1>ReactMeals</h1>
<HeaderCartButton />
</header>
<div className={classes["main-image"]}>
<img src={mealsImage} alt="A table full of delicious food!" />
</div>
</Fragment>
);
};
export default Header;
//HeaderCartButton.js
import CartIcon from "../Cart/CartIcon";
import { useContext } from "react";
import classes from "./HeaderCartButton.module.css";
import CartContext from "../../store/cart-context";
const HeaderCartButton = (props) => {
const ctx = useContext(CartContext);
const numberOfCartItems = ctx.items.reduce((accumulator, item) => {
return accumulator + item.amount;
}, 0);
return (
<button className={classes.button} onClick={ctx.onShowCart}>
<span className={classes.icon}>
<CartIcon />
</span>
<span>Your Cart</span>
<span className={classes.badge}>{numberOfCartItems}</span>
</button>
);
};
export default HeaderCartButton;
Thanks for your help
If you look at your App component, you are using CartContext outside the provider.
function App() {
const ctx = useContext(CartContext);
return (
<CartProvider>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</CartProvider>
);
}
You should modify it so that it is similar to the following, where you are using the context inside the provider.
const Main = () => {
return <CartProvider><App /></CartProvider>
}
function App() {
const ctx = useContext(CartContext);
return (
<>
{ctx.state && <Cart />}
<Header />
<main>
<Meals />
</main>
</>
);
}
I'm building a practice app that uses Unsplash to render users photos. I'm using React and Redux. With react-router-dom, I'm trying to follow the docs but I find it very confusing to set up. Here's what I have so far. When I click on a result out of a returned list of results from a search, I want it to render a user page profile.
index.js (make sure I have react-router-do set up correctly):
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
// import store from './app/store';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import reducers from "./app/reducers/rootReducer";
import * as serviceWorker from './serviceWorker';
const storeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducers, storeEnhancers(applyMiddleware(thunk)));
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
Top component App
import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import Images from "./app/components/Images";
import Search from "./app/components/Search";
import UserProfile from "./app/components/UserProfile";
import "./App.css";
function App() {
return (
<>
<Search />
<Images />
<Router>
<Route link="/userProfile">
<UserProfile />
</Route>
</Router>
</>
);
}
export default App;
search (parent component to searchResults where exists):
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { queryAction } from "../actions/queryAction";
import SearchResults from "./SearchResults";
const Search = (props) => {
const [query, setQuery] = useState("");
console.log(props.searches);
const searchPhotos = async (e) => {
e.preventDefault();
console.log("submitting form");
props.queryAction(query);
};
const showUsers = (user, e) => {
e.preventDefault()
console.log(user)
};
return (
<>
<form className="form" onSubmit={searchPhotos}>
<label className="label" htmlFor="query">
{" "}
</label>
<input
type="text"
name="query"
className="input"
placeholder={`Try "dog" or "apple"`}
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
<button type="submit" className="button">
Search
</button>
</form>
<SearchResults results={props.searches} showUsers={showUsers} />
</>
);
};
const mapStateToProps = (state) => {
return {
searches: state.searches,
};
};
const mapDispatchToProps = (dispatch) => {
return {
queryAction: (entry) => dispatch(queryAction(entry)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Search);
searchResults:
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
import { getUserAction } from "../actions/getUserAction";
import { connect } from "react-redux";
const SearchResults = (props) => {
const { results } = props.results.searches;
const handleClick = (result, e) => {
e.preventDefault();
props.getUser(result.username);
};
return (
<>
{results &&
results.map((result, id) => {
return (
<div key={id}>
<Router>
<Link to="/userProfile" onClick={(e) => handleClick(result, e)}>
{result.username}
</Link>
</Router>
</div>
);
})}
</>
);
};
const mapDispatchToProps = (dispatch) => {
return {
getUser: (query) => dispatch(getUserAction(query)),
};
};
export default connect(null, mapDispatchToProps)(SearchResults);
and finally the UserProfile component:
import React from 'react';
import { connect } from 'react-redux';
const UserProfile = props => {
console.log(props)
return (
<div>
</div>
);
}
const mapStateToProps = state => {
return {
user: state.users
}
}
export default connect(mapStateToProps, null)(UserProfile);
app component
import React from "react";
import { Switch, Route } from "react-router-dom";
import Images from "./app/components/Images";
import Search from "./app/components/Search";
import UserProfile from "./app/components/UserProfile";
import "./App.css";
function App() {
return (
<>
<Search />
<Images />
<Switch>
<Route path="/userProfile/:username">
<UserProfile />
</Route>
</Switch>
</>
);
}
export default App;
SearchResults component
import React from "react";
import { Link } from "react-router-dom";
const SearchResults = (props) => {
const { results } = props.results.searches;
const handleClick = (result, e) => {
e.preventDefault();
props.getUser(result.username);
};
return (
<>
{results &&
results.map((result, id) => {
return (
<div key={id}>
<Link to={`/userProfile/${result.username}`}>
{result.username}
</Link>
</div>
);
})}
</>
);
};
export default SearchResults;
UserProfile component
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { getUserAction } from "../actions/getUserAction";
const UserProfile = props => {
useEffect(() => {
props.getUserAction(props.match.params.username)
},[])
console.log(props)
return (
<div>
{props.user
? <div>{user.username}</div>
: <div>Loading...</div>
}
</div>
);
}
const mapStateToProps = state => {
return {
user: state.users
}
}
const mapDispatchToProps = (dispatch) => {
return {
getUser: (query) => dispatch(getUserAction(query)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(UserProfile);
Edit: Add a param to your link and remove the onclick. Update the Route to expect a :username param. You can access the param through props in UserProfile component.
Make sure to perform the action or access state when mounting the UserProfile component so you have some data when it renders.
Edit 2: Added UserProfile component to answer. You want to dispatch your action when the component is mounting. Also, set a ternary to show "Loading..." if state.user isn't done being fetched.