reactJs onClick handler not working - reactjs

Although defining onClick handler properly, console.log('hi') is not printing on console
import React from 'react';
import './charComponent.css'
const CharOne = (props) =>{
return (<div>
<div className="charOne" onClick={console.log('hi')}>{props.letter}</div>
</div>
)
}
export default CharOne;

console.log('hi') is immediately invoking,
so your onClick has nothing to do (no job). See below code.
import React from 'react';
import ReactDOM from 'react-dom';
const myFunction = () => console.log('hi');
const CharOne = () => <div onClick={myFunction}>Click-Me</div>
ReactDOM.render(<CharOne />, document.getElementById('root'));
If you want to pass an argument, then use an arrow function.
import React from 'react';
import ReactDOM from 'react-dom';
const myFunction = props => console.log(props);
const CharOne = () => <div onClick={() => myFunction('Hello')}>Click-Me</div>
ReactDOM.render(<CharOne />, document.getElementById('root'));

You have to pass a function as parameter:
import React from 'react';
import './charComponent.css'
const CharOne = (props) =>{
return (<div>
<div className="charOne" onClick={() => console.log('hi')}>{props.letter}</div>
</div>
)
}
export default CharOne;

Related

React Native Error: Invalid hook call. Hooks can only be called inside of the body of a function component

I'm programming with some friends a Chess App and now we get an Error implementing the Chess itself.
we get the error in the first const of the function as well as at the Export of App.jsx
Our GitHub Repo: Chedu
App.jsx
import React, { useEffect, useState } from "react";
import "./App.css";
import { gameSubject, initGame, resetGame } from "./Game";
import Board from "./Board";
function App() {
const [board, setBoard] = useState([]); //get Error here
const [isGameOver, setIsGameOver] = useState();
const [result, setResult] = useState();
const [turn, setTurn] = useState();
useEffect(() => {
initGame();
const subscribe = gameSubject.subscribe((game) => {
setBoard(game.board);
setIsGameOver(game.isGameOver);
setResult(game.result);
setTurn(game.turn);
});
return () => subscribe.unsubscribe();
}, []);
return (
<div className="container">
{isGameOver && (
<h2 className="vertical-text">
GAME OVER
<button onClick={resetGame}>
<span className="vertical-text"> NEW GAME</span>
</button>
</h2>
)}
<div className="board-container">
<Board board={board} turn={turn} />
</div>
{result && <p className="vertical-text">{result}</p>}
</div>
);
}
export default App(); //Error Anonymous Function
in Index.js we are Rendering the function and export it.
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
export default ReactDOM.render(
<React.StrictMode>
<DndProvider backend={HTML5Backend}>
<App />
</DndProvider>
</React.StrictMode>,
document.getElementById("root")
);
serviceWorker.unregister();
And at last we want to render the index.js in our ChessBoardPage
import React, { useState } from "react";
import {
StyleSheet,
Text,
View,
Image,
TouchableOpacity,
Dimensions,
Switch,
} from "react-native"; //components
import ReactDOM from "react-dom";
import cheduLogo from "../Pictures/Logo.png";
import loginPictureBlack from "../Pictures/login.png";
import loginPictureWhite from "../Pictures/login_white.png";
import registerPictureBlack from "../Pictures/register.png";
import registerPictureWhite from "../Pictures/register_white.png";
import userPictureBlack from "../Pictures/user.png";
import userPictureWhite from "../Pictures/user_white.png";
import ChessGame from "./ChessBoard/index";
const windowWidth = Dimensions.get("window").width;
const windowHeight = Dimensions.get("window").height;
const { width } = Dimensions.get("window");
const x = 100;
const y = 200;
export default class TempPage extends React.Component {
state = {
switchValue: false,
backgroundColor: "white",
SwitchLogin: loginPictureBlack,
SwitchRegister: registerPictureBlack,
SwitchUser: userPictureBlack,
SunMoon: "☀️",
ShadowBackgroundColor: "white",
};
handleSwitchBackground = () => {
[...]
}
};
render() {
let { backgroundColor } = this.state;
return (
<View
style={{
windowWidth,
windowHeight,
backgroundColor: this.state.backgroundColor,
}}
>
[...]
{/*Content*/}
<View stlye={{ flex: 1 }}>
<ChessGame />
</View>
</View>
);
}
}
[...]
sometime we have issues in react when using anonymous functions. Since anonymous functions aren’t assigned an identifier (via const/let/var), they aren’t persistent whenever this functional component inevitably gets rendered again. This causes JavaScript to allocate new memory each time this component is re-rendered instead of allocating a single piece of memory only once when using “named functions”
consider refactoring your code as follows
import React, { useEffect, useState } from "react";
import "./App.css";
import { gameSubject, initGame, resetGame } from "./Game";
import Board from "./Board";
const App = () => {
const [board, setBoard] = useState([]); //get Error here
const [isGameOver, setIsGameOver] = useState();
const [result, setResult] = useState();
const [turn, setTurn] = useState();
useEffect(() => {
initGame();
const subscribe = gameSubject.subscribe((game) => {
setBoard(game.board);
setIsGameOver(game.isGameOver);
setResult(game.result);
setTurn(game.turn);
});
return () => subscribe.unsubscribe();
}, []);
return (
<div className="container">
{isGameOver && (
<h2 className="vertical-text">
GAME OVER
<button onClick={resetGame}>
<span className="vertical-text"> NEW GAME</span>
</button>
</h2>
)}
<div className="board-container">
<Board board={board} turn={turn} />
</div>
{result && <p className="vertical-text">{result}</p>}
</div>
);
};
export default App;
I am not sure why you are using HTML tags in react native, which think are not yet supported in App.jsx. You should return a <View/> tag instead of div.

Properly LogOut button React

can't get the logout button to work properly. I'm using React and Firebase.
Here is a portion of the code from App.js, where the function was declared
imports
import React, { useState, useEffect } from "react";
import { fire } from './fire';
import LogIn from './LogIn';
import Hero from './Hero';
import './App.css';
declaration
const handleLogout = () => {
fire.auth().signOut();
};
And here is the code from the Hero.js, where the function is used
import React from 'react';
import Contact from "./components/Contact";
const Hero = (handleLogout) => {
return(
<section className="hero">
<nav>
<h2>Welcome</h2>
<button onClick = {handleLogout}>Log Out</button>
</nav>
<div id="contact-form">
<Contact />
</div>
</section>
)
}
export default Hero;
What I'm doing wrong?
you need to get the handleLogout from props properly:
const Hero = ({handleLogout}) => {...}

check state of another functional component

i am new to react, i want to call the state of an outside function, for example :
export default function Child() {
const [succeeded, setSucceeded] = useState(false);
}
export default function Parent() {
if(Child.succeeded){
// do the following
}
}
i know that props are used for const objects only, and i don't want to merge both functions in a signle one to keep things organised, i would like to check for child's state to do the next step, or to callback the parent function with the new state to notify it. is there any way to do it ? Thanks a lot for your time.
Another approach is that you can use the useRef, which is very handy in some cases.
import React, {useState} from "react";
export default function Child({nameRef}) {
const [name, setName] = useState('');
React.useEffect(() => {
nameRef.current = name;
}, [name]);
return (
<>
<input nameRef={nameRef} type="text" onChange={event => setName(event.target.value)} />
</>
);
}
import React, { useState, useRef } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import Child from './Child';
function App() {
let [name, setName] = useState("Nate");
let nameRef = useRef();
const submitButton = () => {
console.log(nameRef.current);
};
return (
<div className="App">
<p>{name}</p>
<div>
<Child nameRef={nameRef} />
<button type="button" onClick={submitButton}>
Submit
</button>
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Trying to pass props and state to a child component

I have a parent functional component and i need to pass props and state to a child functional component, i have managed to pass only one of theme (props or state), the code below displays the fetched data, firstly i've been using const Footer = ({name, adresse, phone}) => {} and then i've replaced it with const Footer = (props) => {} i thought i can pass them this way!!
{props.colorScheme} is accessible in App.js but not in Footer component, should i use context API to pass the props?
FYI, here is my index.js :
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
const colorScheme = root_el.getAttribute("color-scheme");
ReactDOM.render(
<App customBackground={customBackground} colorScheme={colorScheme} />,
root_el
);
My App component
import React, {useEffect, useState, Suspense, lazy } from 'react';
import axios from 'axios';
import Footer from "./components/Footer";
const App = (props) => {
const [infos, setInfos] = useState({});
useEffect( () => {
loadData();
}, []);
const loadData = () => {
axios.get(`https://api`)
.then((res) => {
console.log(res.data);
const infs = setInfos(res.data);
});
}
return (
<div>
<Footer name={infos.name} adresse={infos.adresse} phone= {infos.phone}
</div>
)
};
export default App;
My child component :
import React from 'react';
const Footer = (props) => {
const {name, adresse, phone} = props;
return (
<div>
<h3>{props.colorScheme}</h3>
<span>{name}<span>
<span>{adresse}<span>
<span>{phone}<span>
</div>
)
}
export default Footer;
You can continue to pass the props down to the footer component or you can, as you point out, use a context. Passing the colorScheme via the props is shown below.
Note: Your code was displaying the colorScheme as an h3 in the Footer and I left that as is.
Updated App Component:
import React, {useEffect, useState, Suspense, lazy } from 'react';
import axios from 'axios';
import Footer from "./components/Footer";
const App = (props) => {
const [infos, setInfos] = useState({});
const { colorScheme } = props;
useEffect( () => {
loadData();
}, []);
const loadData = () => {
axios.get(`https://api`)
.then((res) => {
console.log(res.data);
const infs = setInfos(res.data);
});
}
// Footer tag below was missing the tag's closing
// Added colorScheme prop
return (
<div>
<Footer
colorScheme={colorScheme}
name={infos.name}
adresse={infos.adresse}
phone= {infos.phone}/>
</div>
)
};
export default App;
Updated Footer
import React from 'react';
const Footer = (props) => {
const {name, adresse, phone, colorScheme} = props;
return (
<div>
<h3>{colorScheme}</h3>
<span>{name}<span>
<span>{adresse}<span>
<span>{phone}<span>
</div>
)
}
export default Footer;
You can also create a new Context using createContext and useContext so that you can have a single way for all your components to access it. You won't have to pass the color scheme through props. You may want to do both so that you have a global set of default colors and then a prop that lets you override them.

How to show my data in Unordered list format in React?

I am working on a React project, In my project I have four components those are App, Componentc,
Componente, Componentf. Now I am trying to pass an Array from App to Componentf using Context API
I successfuly passed an Array, but the problem is in output the Array is showing like side by
side. but what I am expecting it has to show like Unordered list in html
Please help me to acheive this
This is App.js
import React from 'react';
import Componentc from './Componentc/Componentc';
// import './App.css';
export const UserContext = React.createContext()
const fruits = ['Apple','Orange','Banana','Grapes']
function App() {
return (
<div className="App">
<UserContext.Provider value={fruits}>
<Componentc></Componentc>
</UserContext.Provider>
</div>
);
}
export default App;
This is Componentc
import React from 'react';
import './Componentc.css';
import Componente from '../Componente/Componente';
const Componentc = () => {
return(
<Componente></Componente>
)
}
export default Componentc
This is Componente
import React from 'react';
import './Componente.css';
import Componentf from '../Componentf/Componentf';
const Componente = () => {
return(
<Componentf></Componentf>
)
}
export default Componente
This is Componentf
import React from 'react';
import './Componentf.css';
import { UserContext } from '../App'
const Componentf = () => {
return (
<div>
<UserContext.Consumer>
{
user => {
return <div className='d-block'>{user}</div>
}
}
</UserContext.Consumer>
<h1>Component F</h1>
</div>
)
}
export default Componentf
The value of your context is an array, but you are treating it like an object in the context consumer.
You only need to change return <div className='d-block'>{user}</div> by :
{user => {
return user.map(t => (
<div key={t} className="d-block">
{t}
</div>
));
}}
Although your variables should have meaningful names; I recommend changing the name of the user context and variable to be fruits.
Also, If you are using a recent react version (> 16.8), I also recommend that you use React.useContext API to receive values from context, code become more readable.
const Componentf = () => {
const fruits = React.useContext(FruitContext);
return (
<div>
{fruits.map(fruit => (
<div key={fruit} className="d-block">
{fruit}
</div>
))}
<h1>Component F</h1>
</div>
);
};
Here is a codesandbox demo

Resources