I am trying to learn ReactJS API and want to achive the parent-child but it still doesn't work and I can't find the criteria that I want in those videos.
What I've tried by watching tutorials:
import './App.css';
import Axios from 'axios'
import { useState } from 'react';
function App() {
const [pokeName, setPokeName] = useState("")
const [ability, setAbillity] = useState("")
const data = () => {
Axios.get(`https://pokeapi.co/api/v2/pokemon/${pokeName}`).then((res) => {
console.log(res.data)
setAbillity(res.data)
})
}
return (
<div className="App">
<input placeholder='name of pokemon...' onChange={(event) => {setPokeName(event.target.value.toLowerCase())}} />
<br />
<br />
<button onClick={data}>Click</button>
<br />
<br />
<br />
<h1>Abilities: {ability.power}
</h1>
</div>
);
}
export default App;
Try with pikachu, charizard
const App = () => {
const [pokeName, setPokeName] = React.useState("")
const [ability, setAbillity] = React.useState([])
const data = () => { fetch(`https://pokeapi.co/api/v2/pokemon/${pokeName}`)
.then((res) => res.json())
.then((res) => {
setAbillity(res.abilities)
})
}
return (
<div className="App">
<input placeholder='name of pokemon...' onChange={(event) => {setPokeName(event.target.value.toLowerCase())}} />
<br />
<br />
<button onClick={data}>Click</button>
<br />
<br />
<br />
<h1>Abilities: {ability.map(item => item.ability.name).join(", ")}
</h1>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
<script src="https://unpkg.com/react#16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="root"></div>
Related
I am trying to understand how to share hooks state across components. But it doesn't seem to be sharing. Am I doing something wrong here?
Home.js
export default function Home() {
const [search, setSearch]= useState('');
return (
<div>
<Input search={search} handleChange={setSearch} />
<Products search={search} handleChange={setSearch} />
</div>
)
}
Input.js
export default function Input({search, setSearch}) {
const handleChange = (e) => {
setSearch(e.target.value)
}
return (
<div className='App'>
<input
placeholder='search...'
value={search}
onChange={handleChange}
/>
{search}
</div>
)
}
Live Example:
const { useState } = React;
/*export default*/ function Home() {
const [search, setSearch]= useState('');
return (
<div>
<Input search={search} handleChange={setSearch} />
<Products search={search} handleChange={setSearch} />
</div>
)
}
/*export default*/ function Input({search, setSearch}) {
const handleChange = (e) => {
setSearch(e.target.value)
}
return (
<div className='App'>
<input
placeholder='search...'
value={search}
onChange={handleChange}
/>
{search}
</div>
)
}
const Products = ({search}) => {
return <div>Product: {search}</div>;
};
ReactDOM.createRoot(document.getElementById("root"))
.render(<Home />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.0.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.0.0/umd/react-dom.development.js"></script>
You pass handleSearch as prop in your Home component but Input is expecting setSearch, so just change this line in your Home
return (
<div>
<Input search={search} setSearch={setSearch} /> // change here
<Products search={search} handleChange={setSearch} />
</div>
)
How to make todo list in react.I am following some tutorial how to work with react. This code is using input for adding item to list . How can I add item over h3 element instead input element?
This code is working perfect , I am looking for another way . Thank you
Here is full code .
import { useState } from 'react'
import { v4 as uuidV4 } from 'uuid'
const Header = () => {
const [input, setInput] = useState('')
const [todos, setTodos ] = useState([])
const onInput = (e) => {
setInput(e.target.value)
console.log(input)
}
const onFormSubmit = (e) => {
e.preventDefault()
setTodos([...todos, {id: uuidV4(), title:input, completed:false}])
setInput('')
}
return (
<section className='header'>
<h1>ToDo List</h1>
<form onSubmit={onFormSubmit}>
<input
type="text"
placeholder='Add Item'
className='input'
value={input}
required
onChange={onInput} />
<button
className='btn'
type='submit' > Add </button>
</form>
<br /><br />
<ul>
{todos.map((todo) => (
<li className='todo-list'> // here is output
// <h3> { ? } </h3> it should go todo.title
// can you show me how, pls ?
<input
type="text"
value={todo.title}
className='list'
onChange={(e)=>e.preventDefault()} />
</li>
))}
</ul>
</section>
)
};
export default Header;
Get the title of the todo from the todo object passed to .map() function.
<h3>{todo.title}</h3>
// Get a hook function
const {useState} = React;
const Header = () => {
const [input, setInput] = useState("");
const [todos, setTodos] = useState([]);
const onInput = (e) => {
setInput(e.target.value);
//console.log(input);
};
const onFormSubmit = (e) => {
e.preventDefault();
setTodos([...todos, { id: Math.random(), title: input, completed: false }]);
setInput("");
};
return (
<section className="header">
<h1>ToDo List</h1>
<form onSubmit={onFormSubmit}>
<input
type="text"
placeholder="Add Item"
className="input"
value={input}
required
onChange={onInput}
/>
<button className="btn" type="submit">
{" "}
Add{" "}
</button>
</form>
<br />
<br />
<ul>
{todos.map((todo) => (
<li className="todo-list">
<h3> {todo.title} </h3>
<input
type="text"
value={todo.title}
className="list"
onChange={(e) => e.preventDefault()}
/>
</li>
))}
</ul>
</section>
);
};
// Render it
ReactDOM.render(
<Header />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
I am trying to set the value inside an input in a Form component using KendoReact but the value is not displayed and upon debugging I see that the value is not defined. What am I doing wrong and what is the right approach here? Here is my code:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Form, Field, FormElement } from '#progress/kendo-react-form';
import { Input } from '#progress/kendo-react-inputs';
const InputField1 = (fieldRenderProps) => {
const { label, value } = fieldRenderProps;
return (
<div>
<Input label={label} value={value} />
</div>
);
};
const App = () => {
return (
<div>
<Form
render={(formRenderProps) => (
<>
<br />
<br />
<div>
<Field
name="Field1"
label="Field1 Label"
component={InputField1}
value="value1"
/>
</div>
<br />
<br />
</>
)}
/>
</div>
);
};
ReactDOM.render(<App />, document.querySelector('my-app'));
Here is a working codesandbox You have to pass the other props to the Input:
const InputField1 = (fieldRenderProps) => {
const { label, value, ...others } = fieldRenderProps;
console.log(value);
return (
<div>
<Input label={label} value={value} {...others} />
</div>
);
};
const MyCustomInput = (fieldRenderProps) => {
const {label, value, onChange} = fieldRenderProps;
return (
<Input label={label} value={value} onChange={onChange} />
);
};
const App = () => {
const handleSubmit = (dataItem) => alert(JSON.stringify(dataItem, null, 2));
return (
<Form
onSubmit={handleSubmit}
render={(formRenderProps) => (
<FormElement style={{maxWidth: 650}}>
<Field name={'firstName'} label={'First Name'} component={MyCustomInput} />
<div className="k-form-buttons">
<button type={'submit'} disabled=
{!formRenderProps.allowSubmit} className={'k-button'}>
Submit
</button>
</div>
</FormElement>
)}
/>
);
};
ReactDOM.render(
<App />,
document.querySelector('my-app')
);
you have to add onChange in input tag
Updated CodeSandbox link here
The Add transaction button is not rendering the transaction list in transaction history container
This piece of code {transaction && transaction.map(trans).... is rendering the app UI but the Add transaction button is not generating the Transaction component dynamically in transaction history container}
import React from 'react';
const AddTransaction =
({item,amount,setItem,setAmount,transaction,setTransaction})
=> {
const onSubmit = (e) => {
e.preventDefault();
setTransaction([...transaction,
{
text: item,
amount: amount,
id: Math.floor(Math.random()*1000),
}
] );
setItem('');
setAmount('');
}
return (
<div className='addtransaction-container'>
<div className='add-trans-header'>
<h4>Add New Transaction</h4>
</div>
<form>
<div className="form-control">
<label htmlFor="text">Text</label>
<input type="text" value={item}
onChange={(e) => setItem(e.target.value)}
placeholder="Enter text..." />
</div>
<div className="form-control">
<label htmlFor="amount"
>Amount <br />
(negative - expense, positive - income)
</label>
<input type="number" value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Enter amount..." />
</div>
<button type='button' onClick={onSubmit}
value='submit'
className="btn">
Add transaction
</button>
</form>
</div>
);
}
export default AddTransaction;
The map function is not rendering the Transaction
component in TransactionList.js file
import React from 'react'
import './App.css';
import Transaction from './Transaction.js';
const TransactionList = ({text,transaction,amount}) => {
return (
<div className='transactionlist-container'>
<div className='transactionlist-header-container'>
<h4>
Transaction History
</h4>
</div>
<ul>
<li>
{ transaction.map(trans =>
<Transaction
amount={transaction.amount}
text={transaction.text}
key={transaction.id} />
)}
</li>
</ul>
</div>
)
}
export default TransactionList;
My Transaction.js file have a ul list with the input text and amount but the component is not rendering in the app UI.
import React from 'react'
const Transaction = ({transaction,text,amount}) => {
return (
<div className='transaction'>
{text}<span>{amount}</span>
</div>
)
}
export default Transaction;
I have recreated the app, which is working without any issue.
Here is the link to the working demo: StackBlitz
import React, { useState, useEffect } from "react";
import TransactionList from "./TransactionList";
import AddTransaction from "./AddTransaction";
const App = () => {
const [transaction, setTransaction] = useState([]);
const handleTransaction = value => {
setTransaction([...transaction, value]);
};
const expenseList = transaction.filter(trans => Number(trans.amount) < 0);
const expense = expenseList.reduce(
(acc, curr) => acc + Number(curr.amount),
0
);
const amountList = transaction.filter(trans => Number(trans.amount) > 0);
const amount = amountList.reduce((acc, curr) => acc + Number(curr.amount), 0);
useEffect(() => {
console.log("From app:", transaction);
}, [transaction]);
return (
<div className="transactionlist-container">
<div>
<span>income: {JSON.stringify(amount)}</span>{" "}
<span> total expense: {JSON.stringify(expense)}</span>
<span> balance: {amount + expense}</span>
</div>
<TransactionList transaction={transaction} />
<AddTransaction
transaction={transaction}
handleTransaction={handleTransaction}
/>
</div>
);
};
export default App;
import React from "react";
import Transaction from "./Transaction";
const TransactionList = ({ transaction }) => {
console.log("from tl:", transaction);
return (
<div className="transactionlist-container">
<div className="transactionlist-header-container">
<h4>Transaction History</h4>
</div>
{transaction.map(trans => (
<Transaction amount={trans.amount} text={trans.text} key={trans.id} />
))}
</div>
);
};
export default TransactionList;
import React from "react";
const Transaction = ({ text, amount }) => {
return (
<div className="transaction">
{text}
<span>{amount}</span>
</div>
);
};
export default Transaction;
import React,{useState} from "react"
const AddTransaction =
({handleTransaction})
=> {
const [item,setItem] = useState("")
const [amount, setAmount] = useState(0)
const onSubmit = (e) => {
e.preventDefault();
handleTransaction(
{
text: item,
amount: amount,
id: Math.floor(Math.random()*1000),
}
);
setItem('');
setAmount('');
}
return (
<div
className="inputBox"
>
<div className='add-trans-header'>
<h4>Add New Transaction</h4>
</div>
<form>
<div className="form-control">
<label htmlFor="text">Text</label>
<input type="text" value={item}
onChange={(e) => setItem(e.target.value)}
placeholder="Enter text..." />
</div>
<div className="form-control">
<label htmlFor="amount"
>Amount <br />
(negative - expense, positive - income)
</label>
<input type="number" value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Enter amount..." />
</div>
<button type='button' onClick={onSubmit}
value='submit'
className="btn">
Add transaction
</button>
</form>
</div>
);
}
export default AddTransaction;
I'm very new to Reactjs and i try to learn by building something easy but i'm stuck at this error "TypeError: Cannot read property 'temp' of undefined" when i try to render the data fetched from openweathermap and i really don't know what i am doing wrong.
Any help please?
import React, {useState, useEffect} from "react"
import Weather from "./Weather"
import Loading from "./Loading"
const App = () =>{
const [data, setData] = useState([]);
const [text, setText] = useState("");
const [loading, setLoading] = useState(false);
const submitHandler = (e) =>{
e.preventDefault();
if(loading){
return <Loading />
}
}
const fetchWeather = async () =>{
try {
setLoading(true);
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${text}&appid=4d8fb5b93d4af21d66a2948710284366&units=metric`);
const weather = await response.json();
setData(weather);
console.log(data);
setLoading(false);
} catch (error) {
console.log(error);
}
}
useEffect(() =>{
fetchWeather();
}, [text]);
return (
<section>
<form type="submit" className="form" onSubmit={submitHandler}>
<input type="text" value={text} onChange={(e) =>setText(e.target.value)} />
<button type="submit" className="btn">Search</button>
</form>
<Weather data={data} />
</section>
);
}
Weather component
import React from "react"
const Weather = ({data}) =>{
return (
<div>
{ (data !== "undefined") ? (
<section className="weather">
<div className="title">
<h2>{data.name}</h2>
</div>
<div className="today">
<div className="info">
<h3>{Math.floor(data.main.temp)} C</h3>
<p>{data.weather[0].description}</p>
</div>
<div className="icon">
</div>
</div>
</section>
) : ("")}
</div>
);
}
Try this way
<section>
<form type="submit" className="form" onSubmit={submitHandler}>
<input type="text" value={text} onChange={(e) => setText(e.target.value)} /> <button type="submit" className="btn">Search</button>
</form>
{data ? <Weather data={data} />: null}
</section>
);
Fixed by doing this in Weather component after some more google search.Thanks to all who responded and helped me with this.
Is this a good solution for future projects if i will have the same error?
import React from "react"
const Weather = ({data}) =>{
console.log(data);
return (
<div>
{(data.main && data.sys && data.weather) ? (
<section className="weather">
<div className="title">
<h2>{data.name}</h2>
</div>
<div className="today">
<div className="info">
<h3>{Math.floor(data.main.temp)} C</h3>
<p>{data.weather[0].description}</p>
</div>
<div className="icon">
</div>
</div>
</section>
) : null}
</div>
);
}