State change causing rerendering of the APP component - javascript

I added an onChange event to the Editor.js file, it sets the value of the value variable using setValue that causes rerender of the App component on every change. Values of both value and query are needed in Editor.js and Sidebar.js. Is there any better way to do this to improve the performance?
App.js Code:
import React, { Suspense, useState } from "react";
import "./assets/output.css";
import Footer from "./components/layouts/Footer";
import Navbar from "./components/layouts/Navbar";
import Sidebar from "./components/layouts/Sidebar";
import TableSection from "./components/table/TableSection";
const Editor = React.lazy(() => import("./components/editor/Editor"));
const App = () => {
const [query, setQuery] = useState("");
const [value, setValue] = useState("select * from customers");
return (
<div className="grid grid-cols-layout-desktop grid-rows-layout-desktop bg-gray-600 h-screen">
<Navbar />
<Sidebar setQuery={setQuery} setValue={setValue} />
<Suspense fallback={<div>Loading..</div>}>
<Editor setQuery={setQuery} value={value} setValue={setValue} />
</Suspense>
{query ? <TableSection query={query} /> : null}
<Footer />
</div>
);
};
export default App;

Related

In React; is it possible to pass down a component name to create a flexible page switch component?

thanks for checking out my question. I'm wondering if what I am trying to do is possible, and why it doesn't work the way I am trying.
I have a toggle switch that allows you to change between pages simply. I'm wondering if I can make this toggle recyclable by being able to pass the component names down. Please see my attempt below.
Parent Component calling the Switch page toggler:
import React from "react";
import SwitchPages from "../component/SwitchPages/SwitchPages";
import StickyNoteComponent from "../component/StickyNote/StickyNoteComponent";
const HomePage = () => {
return (
<div className="page">
<SwitchPages
page1={"WeatherDisplayComponent"}
page2={"JokeComponent"}
text1={"Weather"}
text2={"Jokes"}
/>
<StickyNoteComponent />
</div>
);
};
export default HomePage;
The SwitchPage component that contains the toggle:
import React, { useState } from "react";
import Switch from "react-switch";
import JokeComponent from "../DailyJoke/JokeComponent";
import WeatherDisplayComponent from "../WeatherDisplay/WeatherDisplayComponent";
const SwitchPages=({page1,page2,text1,text2}) =>{
const [checked, setChecked] = useState(false);
return (
<div className="component">
<div className="switch">
<h1>{text1}</h1>
<Switch
offColor="#9BCA31"
onColor="#E3E545"
uncheckedIcon={false}
checkedIcon={false}
className="switch-toggle"
checked={checked}
onChange={() => {
setChecked(!checked);
}}
/>
<h1>{text2}</h1>
</div>
{checked === false ? <{page1} /> : <{page2} />}
</div>
);
}
export default SwitchPages;

Why is a react element not updating?

I have a react component that takes the input from a materialUi text form and uses a useState hook to update. On submit I want it to update another variable to the value. This is being used in an h1 element. However, the h1 element is not updating. I know the variable is updating because I log it in the console and it updates.
import React, { useState } from 'react';
import CssBaseline from '#mui/material/CssBaseline';
import { ThemeProvider, createTheme } from '#mui/material/styles';
import Alert from '#mui/material/Alert';
import { TextField } from '#mui/material';
import Button from '#mui/material/Button';
import './style.css';
import { useEffect } from 'react';
const darkTheme = createTheme({
palette: {
mode: 'dark',
},
});
export default function App() {
const [myValue, setValue] = useState('') // The original hook
let headingText = 'Hello World'
let onSubmit = (e) => {
e.preventDefault();
headingText = myValue;
console.log(headingText);
console.log(myValue);
};
return (
<>
<title>Text Changer</title>
<div className='joe'>
<ThemeProvider theme={darkTheme}>
<React.Fragment>
<CssBaseline />
<Alert severity="success">Page Loaded</Alert>
<h1>{headingText}</h1> // the h1 I want to update
<form onSubmit={onSubmit}>
<TextField id="outlined-basic" label="Search Text" variant="outlined" value={myValue} onChange={(e) => setValue(e.target.value)}/>
<br />
<br />
<Button variant="contained" color="primary" type="submit">Submit</Button>
</form>
</React.Fragment>
</ThemeProvider>
</div>
</>
);
}
You'll want to useState for that as well
const [headingText, setHeadingText] = useState('Hello World');
// ...
setHeadingText(myValue);
You have to create a state as
const [headingText, setHeadingText] = useState("Hello World");
CODESANDBOX DEMO.
and then onClick of a button you have to update state. React will re-render the component if the state changes
let onSubmit = (e) => {
e.preventDefault();
setHeadingText(myValue);
};

Objects are not valid as a React child. found: object with keys {background, color}

i am trying to setting up darkMode button, but i got this error ... Uncaught Error: Objects are not valid as a React child (found: object with keys {background, color}). If you meant to render a collection of children, use an array instead.
here is my data..................
my Contextjs component......
import { createContext, useReducer } from "react";
export const themeContext = createContext();
const initialState = {darkMode : true};
const themeReducer = (state, action) =>{
switch(action.type){
case'toggle':
return {darkMode : !state.darkMode};
default:
return state;
}
};
export const ThemeProvider = (props)=>{
const [state, dispatch] = useReducer (themeReducer, initialState);
return(
<themeContext.Provider value={{state, dispatch}}>
{props.children}
</themeContext.Provider>
);
};
my AppJs component.......
import Navbar from "./Components/Navbar/Navbar";
import "./App.css"
import { Intro } from "./Components/Intro/Intro";
import Services from "./Components/Services/Services";
import Experience from "./Components/Experience/Experience"
import Works from "./Components/Works/Works"
import Portfolio from "./Components/Portfolio/Portfolio"
import Testimonials from './Components/Testtimonials/Testimonials'
import Contact from "./Components/Contact/Contact"
import Footer from "./Components/Footer/Footer"
import {themeContext} from './Context'
import { useContext } from "react";
function App() {
const theme = useContext(themeContext);
const darkMode = theme.state.darkMode;
return (
<div className="App">
style={{
background : darkMode? 'black' : '',
color : darkMode? 'white' : ''
}}
<Navbar />
<Intro />
<Services />
<Experience />
<Works />
<Portfolio/>
<Testimonials/>
<Contact />
<Footer />
</div>
);
}
export default App;
and here is IndexJs..........
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {ThemeProvider} from './Context';
ReactDOM.render(
<ThemeProvider>
<App />
</ThemeProvider>,
document.getElementById('root')
);
and error is:- Uncaught Error: Objects are not valid as a React child (found: object with keys {background, color}). If you meant to render a collection of children, use an array instead.
You have to pass style prop to component.
<div
className="App"
style={{
background: darkMode ? "black" : "",
color: darkMode ? "white" : "",
}}
>
I would rather prefer, create 2 classes dark and light and use like this:
<div className={`App ${darkMode ? "dark" : "light"}`}>
It's trying to render your style object as a child of the div, update it so it is an attribute of the div.
<div
className="App"
style={{
background: darkMode ? "black" : "",
color: darkMode ? "white" : "",
}}
>
<Navbar />
<Intro />
<Services />
<Experience />
<Works />
<Portfolio />
<Testimonials />
<Contact />
<Footer />
</div>

How can I show a modal using an animation with Tailwind and react.js?

I am trying when I click on a modal to have an animation to show the modal but I don't achieve to do that using Tailwind and react.
Here is my code :
import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";
import Wrapper from "./Wrapper";
import Input from "./Input";
import "./styles.css";
import Button from "./Button";
import Modal from "./Modal";
function App() {
const [showModal, setShowModal] = useState(false);
const handleShowModal = useCallback(() => {
setShowModal(!showModal);
}, [showModal]);
const handleCloseModal = useCallback(() => {
setShowModal(false);
}, []);
return (
<div className="p-4">
<h1 className="text-red-500 text-center">PlayGround</h1>
<Wrapper className="p-2">
<Input />
</Wrapper>
<Wrapper className="p-2">
<Button onClick={handleShowModal}>Show Modal</Button>
{showModal && <Modal onCancel={handleCloseModal} />}
</Wrapper>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
And you can see my full code here :
my full project
I would like something like that :
the goal
How can I do that ?
Thank you very much !
I recommend using headless ui
you can use like this
import { Transition } from '#headlessui/react'
import { useState } from 'react'
function MyComponent() {
const [isShowing, setIsShowing] = useState(false)
return (
<>
<button onClick={() => setIsShowing((isShowing) => !isShowing)}>
Toggle
</button>
<Transition
show={isShowing}
enter="transition-opacity duration-75"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity duration-150"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
I will fade in and out
</Transition>
</>
)
}

How to redirect to a url along with a component in react such that props passed to the component are not lost

When onClick event is triggered, I want to redirect to a new component (props passed to it) with a new url.
My App.js
import React from "react";
import Main from "./Components/Main/Main";
import "bootstrap/dist/css/bootstrap.min.css";
import styles from "./App.module.css";
import { BrowserRouter as Router, Route} from "react-router-dom";
import SearchBar from "./Components/SearchBar/SearchBar";
import AnimeInfo from "./Components/AnimeInfo/AnimeInfo";
import Cards from "./Components/Cards/Cards"
const App = () => {
return (
<Router>
<div className={styles.container}>
<SearchBar />
<Route path="/" exact component={Main} />
<Route path="/anime/info" component={AnimeInfo} />
<Route path="/anime/cards" component={Cards} />
</div>
</Router>
);
};
export default App;
In the following component, I am passing props to a component but I want to redirect to the url too, but doing so, the props passed that component are lost and I just get redirected
import React, { useEffect, useState } from "react";
import { apiDataTop, apiDataUpcoming, apiDataDay } from "../../api";
import styles from "./TopAnime.module.css";
import AnimeInfo from "../AnimeInfo/AnimeInfo";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
Redirect,
} from "react-router-dom";
const TopAnime = () => {
const [animeData, setAnimeData] = useState([]);
const [animeDataHype, setAnimeDataHype] = useState([]);
const [animeDataDay, setAnimeDataDay] = useState([]);
const [image_url, setImageUrl] = useState("");
useEffect(() => {
callApi();
}, []);
const callApi = async () => {
const results = await apiDataTop();
const hypeResults = await apiDataUpcoming();
const dayResults = await apiDataDay();
setAnimeData(results);
setAnimeDataHype(hypeResults);
setAnimeDataDay(dayResults);
};
console.log(animeDataDay);
return (
<div>
<h1>Recent Release</h1>
<div className={styles.container}>
<br />
{animeDataDay === []
? null
: animeDataDay.map((anime) => {
return (
<a
href
onClick={(event) => {
event.preventDefault();
let animeName = anime.title;
animeName = animeName.replace(/\s+/g, "");
setImageUrl(anime.image_url);
console.log("image url original", anime.image_url);
console.log("image url", image_url);
}}
className={styles.move}
>
<img src={anime.image_url} alt="anime" />
<div className={styles.size}>
<h5>
<b>{anime.title}</b>
</h5>
</div>
</a>
);
})}
{image_url ? (
<Router>
// below commented approch first display the component on the same page and then redirects to the url
// but the props passed are lost !
// <Link to="/anime/info">
// <AnimeInfo image_url={image_url} />
// {window.location.href = `/anime/info`}
// </Link>
<Route
path="/anime/info"
render={() => <AnimeInfo image_url={image_url} />}
/>
</Router>
) : null}
</div>
export default TopAnime;
Following is the component, to whom I want to pass props and use the data passed to display (on a whole new page)!
import React, { useEffect, useState } from "react";
import styles from "./AnimeInfo.module.css";
console.log("The data image props issss", props.image_url);
return (
<div className={styles.container}>
<h1> I am info component</h1>
<img src={props.image_url} alt="anime" />
</div>
);
};
export default AnimeInfo;
Why not use the state property in history.push()?
See it in action here
use the history package.
then create a file at 'src/history.js'
import { createBrowserHistory } from 'history';
export default createBrowserHistory();
then in your component
import history from './history'
history.push({
pathname: '/path',
data_name: dataObject,
});
Then you can access the props in your other component:
this.props.location.data_name
Use render method in router
const renderComponent = (props, Component) => {
// write logic if needed
return <Component {...props} />
}
<Route path="/earner" render={(props) => renderComponent(props, Main)}/>

Categories

Resources