How to get a variable back from a called component - javascript

I have a problem: I have my main class Input.js. A user can select a photo and upload it. The problem is I want to check if the user uploaded a photo or not when he press the button. For example I can give from Profilepic.js to Pic.js the picture as props. But how could I get back a variable? For example I want to set the variable in Profilepic.js and when the user I pressing the button the method onClick() should executed. Inside of this method it should check which value the variable isPreview has. And if the User hasnt uploaded a picture there should be a lable signaling him that he has to upload an image to continue.
Input.js
import React, { useState, useEffect } from 'react';
import { InputTags } from 'react-bootstrap-tagsinput';
import 'react-bootstrap-tagsinput/dist/index.css';
import './Input.css';
import Profilepic from './Profilepic';
const Input = () => {
const checkAll = () => {
// Call Preview from Profilepic.js
}
return (
<div className="body-container">
<Profilepic></Profilepic>
<div className="row gutters">
<div className="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-12">
<div className="text-right">
<button type="button" id="submit" name="submit" className="btn btn-primary" onClick={checkAll}>Speichern & Weiter <i class="fas fa-paper-plane"></i></button>
</div>
</div>
</div>
</div>
);
}
export default Input
Profilepic.js
import React, { useState } from "react";
import { Pic } from "./Pic.js";
const Profilpic = () => {
const [preview, setPreview] = useState(null);
const [isPreview, setIsPreview] = useState(false);
const fileSelectedHandler = (event) => {
try {
console.log(event.target.files[0]);
if (event.target.files[0].size > 70001680) {
alert("File is too big! Wie Samys Dick");
} else {
let img = URL.createObjectURL(event.target.files[0]);
setPreview(img);
setIsPreview(true);
}
}
catch (err) {
}
};
return (
<div>
{preview ? (
<div>
<label htmlFor="myInput">
<Pic preview={preview}></Pic>
</label>
<input
id="myInput"
style={{ display: "none" }}
type={"file"}
onChange={fileSelectedHandler}
/>
</div>
) : (
<div>
<label htmlFor="myInput">
<i className="fas fa-user-circle"></i>
</label>
<input
id="myInput"
style={{ display: "none" }}
type={"file"}
accept=".png,.jpg,.jpeg, .jfif"
onChange={fileSelectedHandler}
/>
</div>
)}
</div>
);
};
export default Profilpic;
Pic.js
import React from "react";
import "./Photo.css";
const STYLES = ["btn--primary", "btn--outline", "btn--test"];
const SIZES = ["btn--medium", "btn--large"];
export const Pic = ({ preview }) => {
//const checkButtonStyle = STYLES.includes(buttonStyle) ? buttonStyle : STYLES[0];
//const checkButtonSize = SIZES.includes(buttonSize) ? buttonSize : SIZES[0];
// Püsh for Samy
return (
<div class="profilepic">
<img
class="profilepic__image"
src={preview}
width="120"
height="120"
alt="Profibild"
/>
<div class="profilepic__content">
<span class="profilepic__icon">
<i class="fas fa-camera"></i>
</span>
<span class="profilepic__text">Profilbild ändern</span>
</div>
</div>
);
};
Description of the Problem

You can use the useImperativeHandle. This requires a bit of a wrapping of
Profilepic
import React, { forwardRef, useImperativeHandle, useState } from "react";
import { Pic } from "./Pic.js";
function Profilepic(props, ref) {
const [preview, setPreview] = useState(null);
const [isPreview, setIsPreview] = useState(false);
useImperativeHandle(
ref,
() => ({ isPreview }),
[isPreview]
);
...
return (
...
);
};
export default forwardRef(Profilepic);
Input
import React, { useState, useEffect, useRef } from 'react';
import Profilepic from './Profilepic';
const Input = () => {
const profilePicRef = useRef();
const checkAll = () => {
// access profilePicRef.current.isPreview
}
return (
<div className="body-container">
<Profilepic ref={profilePicRef} />
...
<button
type="button"
id="submit"
name="submit"
className="btn btn-primary"
onClick={checkAll}
>
Speichern & Weiter <i class="fas fa-paper-plane" />
</button>
...
</div>
);
}

Related

Error Functions are not valid as a React child. This can happen if you return a Component instead of <Component /> from render

I tell you that I am making a shopping cart and I get the following warning "Functions are not valid as a React child. This can happen if you return a Component instead of from render. Or maybe you meant to call this function instead of returning it.", what I am doing is passing through an event information to the father from the son to be used later in the Cart.
the codes are these:
ItemDetial (detail of the product selected by the customer):
import React, { useState } from "react";
import '../App.css';
import 'materialize-css/dist/css/materialize.css';
import Count from './ItemCount';
import { Link } from "react-router-dom";
export const ItemDetail = (({item}) => {
const [itemSell, setItemSell] = useState(false);
const onAdd = (count) => {
setItemSell(true);
}
return (
<>
{
<main className="row soloProduct" id= {item.id}>
<aside>
<img src={item.image} alt="item" className="itemImg responsive-img"/>
</aside>
<article>
<div className=" col s12 m8">
<h5 className="itemName">{item.title}</h5>
</div>
<div className="col s12 m4">
<p className="itemPrice"> {item.price}</p>
</div>
<div className="col s12 m12">
<p className="itemDescription">{item.description}</p>
</div>
<div className="col s12">
{
itemSell ? <Link to="/cart"><button className="waves-effect waves-light btn-large">Finalizar Compra</button></Link> : <Count stockInitial={5} onAdd= { onAdd } />
}
</div>
</article>
</main>
}
</>
)
});
export default ItemDetail;
ItemCount (it is a counter so that the client has the possibility of buying more than one product):
import React, { useState} from 'react';
import 'materialize-css/dist/css/materialize.css';
import '../App.css';
import {FontAwesomeIcon} from '#fortawesome/react-fontawesome';
import {faPlus, faMinus, faPowerOff} from '#fortawesome/free-solid-svg-icons';
const ItemCount = ({stockInitial, initial = 0, onAdd}) => {
const [contador, setContador] = useState(initial)
const [stock, setStock] = useState(stockInitial)
const sumar = () => {
setContador(contador + 1)
setStock(stock - 1);
avisarStock();
}
const restar= () => {
if(contador > 0){
setContador(contador - 1);
setStock(stock + 1);
}
else
{
setContador(0);
}
}
const reset = () =>{
setContador(0);
setStock(stockInitial);
}
const avisarStock = () => {
if(stock > 0 ){
}
else{
alert('No podemos enviar su envio no hay stock');
setStock(0);
setContador(contador)
}
}
const agregarAlCarrito = () => {
onAdd(contador);
}
return(
<>
<div className=" row left text">Stock: {stock}</div>
<article>{contador}</article>
<div className="buttonCount">
<button onClick={sumar}>
<FontAwesomeIcon icon ={faPlus}/>
</button>
<button onClick={restar}>
<FontAwesomeIcon icon={faMinus}/>
</button>
<button onClick={reset}>
<FontAwesomeIcon icon={faPowerOff}/>
</button>
<br/><h2>{avisarStock}</h2>
<button onClick={agregarAlCarrito}> Agregar al carrito </button>
</div>
</>
)
}
export default ItemCount;
if you can give me a hand
Thank you
Hey juan hope you're doing well..
I just found a single mistake that is your ( brackets in itemdetails component. check the same your code given below-
import React, { useState } from "react";
import '../App.css';
import 'materialize-css/dist/css/materialize.css';
import Count from './ItemCount';
import { Link } from "react-router-dom";
const ItemDetail = ({item}) => {
const [itemSell, setItemSell] = useState(false);
const onAdd = (count) => {
setItemSell(true);
}
return (
<>
{
<main className="row soloProduct" id= {item.id}>
<aside>
<img src={item.image} alt="item" className="itemImg responsive-img"/>
</aside>
<article>
<div className=" col s12 m8">
<h5 className="itemName">{item.title}</h5>
</div>
<div className="col s12 m4">
<p className="itemPrice"> {item.price}</p>
</div>
<div className="col s12 m12">
<p className="itemDescription">{item.description}</p>
</div>
<div className="col s12">
{
itemSell ? <Link to="/cart"><button className="waves-effect waves-light btn-large">Finalizar Compra</button></Link> : <Count stockInitial={5} onAdd= { onAdd } />
}
</div>
</article>
</main>
}
</>
)
};
export default ItemDetail;
If this works just lemme know. thanks

Deleting multiple items in checkboxes at once using REACT

I'm trying to delete multiple items at once for checkboxes in REACT, but the code does not seem to delete the items being checked.
Here's my approach to doing this. I made a function in tasks.jsx file
called add_ids_to_be_deleted to append the id that was being checked
in the checkbox to an array of ids to be deleted called list_of_ids.
This function is called in the child component in priorityLists.jsx.
When the user clicks the delete button, I created a useEffect to
filter out all the items in toDo whose ids are not included in the ids
to be deleted.
The problem is it keeps deleting the last item whenever I check a checkbox regardless of the order.
For example, I add 3 checkboxes and
check the first checkbox to delete it. Instead of the first checkbox
being deleted, the last item is deleted even though it wasn't being
checked.
tasks.jsx
import React, { useState, useEffect } from 'react';
import { Delete, Refresh, Add } from '../components/Actions';
import { Header } from '../components/Header';
import ToDoList from '../components/TaskList';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faPlus, faTrash } from '#fortawesome/free-solid-svg-icons';
import { v4 as uuidv4 } from 'uuid';
function Task() {
const [toDo, setToDo] = useState([]);
const [idsToRefresh, setIdsToRefresh] = useState([]);
const [list_of_Ids, setIds] = useState([]);
const [filter_now, setFilterNow] = useState(false);
function addToDos() {
const id = uuidv4();
setToDo(
toDo.concat({
_isKey: id,
_checked: false,
value: <ToDoList _onDelete={add_Ids_ToBe_Deleted} _key={id} />
})
);
setIdsToRefresh(idsToRefresh.concat(id));
}
function switchNow() {
if (!filter_now) {
setFilterNow(true);
} else {
setFilterNow(false);
}
}
useEffect(() => {
if (toDo[0] !== undefined) {
setToDo(
toDo.filter(item => {
return !list_of_Ids.includes(item._isKey);
})
);
}
}, [filter_now]);
function add_Ids_ToBe_Deleted(_id_ToBe_Deleted) {
setIds(item => [...item, _id_ToBe_Deleted]);
}
function refresh() {
setToDo(
toDo.filter(item => {
return !idsToRefresh.includes(item._isKey);
})
);
}
return (
<div className="main-content">
<div className="container-fluid">
<div className="row underline">
<div className="col">
<div className="row">
<div className="col-3 pt-2">
<Refresh _refresh={refresh} />
</div>
<div className="col-6 text-center">
<Header header={'Tasks'} />
</div>
<div className="col-3 pt-2">
<button className="float-right">
<FontAwesomeIcon
onClick={switchNow}
icon={faTrash}
size="2x"
/>
</button>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col">
{toDo.map(item => {
return (
<div>
<ul>
<li>{item.value}</li>
</ul>
</div>
);
})}
</div>
</div>
<div className="row">
<div className="col pr-4">
<button onClick={addToDos} className="float-right" name="add">
<FontAwesomeIcon icon={faPlus} size="2x" />
</button>
</div>
</div>
</div>
</div>
);
}
export default Task;
Tasklist.jsx
import React from 'react';
import { PriorityLists } from '../components/PriorityLists';
import { Priority } from './Actions';
function ToDoList(props) {
return (
<PriorityLists
_onDelete={props._onDelete}
keys={props._key}
name="toDoList"
>
<Priority />
</PriorityLists>
);
}
export default ToDoList;
Prioritylists.jsx
import React, { useState, useEffect } from 'react';
import { Priority } from './Actions';
function PriorityLists(props) {
return (
<form>
<div className="input-group mb-3">
<div className="input-group-prepend">
<div className="input-group-text">
<input
is_checked={false}
unique_Key={props.keys}
onClick={e =>
props._onDelete(
e.target.attributes.getNamedItem('unique_Key').value
)
}
id="check-item"
type="checkbox"
aria-label="Checkbox for following text input"
/>
</div>
</div>
<textarea class="form-control" rows="1" name={props.name}></textarea>
{props.children}
</div>
</form>
);
}
export { PriorityLists };

How to change the button text on click

import React from "react";
function ToDoItem(props) {
function but(){
document.getElementById('testBtn').value='ok'
}
return (
<div
>
<li>{props.text} <button class="deletebtn" onClick={() => {
props.onChecked(props.id);
}}><span>Delete</span></button>
</li>
<hr/>
<input type="button" value="Test" id="testBtn" onclick={but}/>
</div>
);
}
export default ToDoItem;
I wrote this function to change the value of the id from from "Test" to "ok", but I donot know why it is not working. When I use onclick="but()" instead of onclick={but}, it says the function but() is unused. I am not why is this not working. Please help
This is how you do it in React. You dont mix react, with DOM manipulation:
import React, {useState} from "react";
function ToDoItem(props) {
const [buttonText, setButtonText] = useState('Test');
return (
<div>
<li>
{props.text}
<button
class="deletebtn"
onClick={() => {
props.onChecked(props.id);
}}
>
<span>Delete</span>
</button>
</li>
<hr />
<input
type="button"
value={buttonText}
id="testBtn"
onClick={() => setButtonText("Ok")}
/>
</div>
);
}
export default ToDoItem;
And an, update for follow-up question. With the styling it depends what kind of styling you use in your react application. But you could use inline styling to get the behaviour you want. I for one use styled components when working in React...here's an updated code.
import React, { useState } from "react";
function ToDoItem(props) {
const [buttonText, setButtonText] = useState("Test");
const [buttonColor, setButtonColor] = useState("red");
const changeButton = () => {
setButtonText(buttonText === "Test" ? "Ok" : "Test");
setButtonColor(buttonColor === "red" ? "blue" : "red");
};
return (
<div>
<li>
{props.text}
<button
class="deletebtn"
onClick={() => {
props.onChecked(props.id);
}}
>
<span>Delete</span>
</button>
</li>
<hr />
<input
style={{ backgroundColor: buttonColor }}
type="button"
value={buttonText}
id="testBtn"
onClick={changeButton}
/>
</div>
);
}
export default ToDoItem;
Adding to my comments, your code reimplemented with hooks.
import React, { useState } from "react";
function ToDoItem(props) {
const [value, setValue] = useState('Test');
function but(){
setValue('ok');
}
return (
<div>
<li>{props.text} <button class="deletebtn" onClick={() => {
props.onChecked(props.id);
}}><span>Delete</span></button>
</li>
<hr/>
<input type="button" value={value} id="testBtn" onclick={but}/>
</div>
);
}
export default ToDoItem;

Switch Button using Hooks in ReactJS to display different content

I'm trying to create a switch button that can display 2 different contents depending on which of the 2 buttons I click on using the hooks in react js.
I would like to display for example a sentence "You have clicked on the left button" when I click on the left one and the opposite when I click on the right one.
I would like the content to be displayed just below the switch buttons.
In addition, I would like my button to remain active when I clicked on it. That is to say, it should be of a darker color since it is active.
Do you have an idea?
This is the piece of code :
import React,{useState} from 'react';
import {Button} from "react-bootstrap";
import {FontAwesomeIcon} from "#fortawesome/react-fontawesome";
import {faBars, faChartLine} from "#fortawesome/free-solid-svg-icons";
import CustomerTable from "../CustomerTable/CustomerTable";
export default function HookButtonSwitch(props) {
const [resultatContenu, setResultatContenu] = useState('Content initial');
const [state, setState] = useState(false);
const handleEventSwitchButton = event => {
let resultatContenu;
switch(event.target.id) {
case 'stats':
console.log("Coucou Stats");
resultatContenu = 'Stats';
break;
case 'list':
console.log("Coucou List");
resultatContenu = 'LIST';
break;
}
setResultatContenu(resultatContenu);
};
const toggle = () => setState(!state);
return (
<div>
<br />
<Button
id="list"
variant="light"
className="border-radius-left"
onClick={handleEventSwitchButton}
>
<FontAwesomeIcon icon={faBars} />
</Button>
<Button
id="stats"
variant="light"
className="border-radius-right"
onClick={handleEventSwitchButton}
>
<FontAwesomeIcon icon={faChartLine} />
</Button>
<div> {resultatContenu} </div>
{/* <p>-------</p>
<div onClick={toggle}>
<div className="toggle">
{state ? <div>Yes! 👍 </div> : <div>No! 👎</div>}
</div>
</div>
*/}
</div>
)
}
Thank you in advance.
check hope its work
import React,{useState} from 'react';
import {Button} from "react-bootstrap";
import {FontAwesomeIcon} from "#fortawesome/react-fontawesome";
import {faBars, faChartLine} from "#fortawesome/free-solid-svg-icons";
import CustomerTable from "../CustomerTable/CustomerTable";
export default function HookButtonSwitch(props) {
const [resultatContenu, setResultatContenu] = useState('Content initial');
const [state, setState] = useState(false);
const handleEventSwitchButton = (event,condition) => {
this.setState({buttonSwitch:condition})
let resultatContenu;
switch(event.target.id) {
case 'stats':
console.log("Coucou Stats");
resultatContenu = 'Stats';
break;
case 'list':
console.log("Coucou List");
resultatContenu = 'LIST';
break;
}
setResultatContenu(resultatContenu);
};
const toggle = () => setState(!state);
const {buttonSwitch=false}= this.state
return (
<div>
<br />
<Button
id="list"
variant="light"
className="border-radius-left"
style={buttonSwitch&&{backgroundColor:'black'}}
onClick={(e)=>handleEventSwitchButton(e,true)}
>
<FontAwesomeIcon icon={faBars} />
</Button>
<Button
id="stats"
variant="light"
className="border-radius-right"
style={!buttonSwitch&&{backgroundColor:'black'}}
onClick={(e)=>handleEventSwitchButton(e,false)}
>
<FontAwesomeIcon icon={faChartLine} />
</Button>
<div> {resultatContenu} </div>
{/* <p>-------</p>
<div onClick={toggle}>
<div className="toggle">
{state ? <div>Yes! 👍 </div> : <div>No! 👎</div>}
</div>
</div>
*/}
</div>
)
}

How i can use html <form> using redux?

I do not use html in form, because when I use and I click on <button type = "button" className = "button button2" onClick = {() => this.login ()}> logar </ button>, the page of a refresh and the error message some. But when I do not use it, this message appears to me in the console: [DOM] Password field is not contained in a form: (More info: https :// goo.gl/9p2vKq)
import React, {Component, Fragment} from 'react'
import {Redirect} from 'react-router-dom'
import { connect } from 'react-redux'
import ActionCreator from '../redux/actionCreators'
import styled from 'styled-components'
import Button from './elements/Button'
const BodyLogin = styled.div`
#formulario{
max-width: 850px
}`
import {Redirect} from 'react-router-dom'
class ScreensLogin extends Component {
constructor(props){
super(props)
this.state = {
form: {
email: '',
passwd: '',
}
}
}
componentDidMount(){
if (this.props.auth.error){
this.props.reset()
}
}
handleChange = field => event => {
const form = {
...this.state.form
}
form[field] = event.target.value
this.setState({form})
}
login = () => {
const {email, passwd} = this.state.form
this.props.login(email, passwd)
}
render(){
return (
<Fragment>
<BodyLogin>
<form> //this is my problem
<div className='form-group mx-auto' id="formulario">
<div className="input-group">
<div className="input-group-prepend">
<span className="input-group-text" id="">Email</span>
</div>
<input className="form-control" autoComplete='on' value={this.state.form.email} type="text" onChange={this.handleChange('email')} ></input>
</div>
<div className="input-group mt-5 mb-5">
<div className="input-group-prepend">
<span className="input-group-text" id="">Senha</span>
</div>
<input className="form-control" autoComplete='on' value={this.state.form.passwd} type="password" onChange={this.handleChange('passwd')} ></input>
</div>
<Button>
{<button type="button" className="button button2 " onClick={() => this.login()}>logar</button>}
</Button><br/><br/>
{this.props.auth.isAuth && <Redirect to={'/'}/>}
{
this.props.auth.error && <p className="text-danger">{this.props.auth.errorMessage}</p>
}
{
this.props.auth.isSigningin && <p className="text-info">Carregando...</p>
}
</div>
</form>
</BodyLogin>
</Fragment>
)
}
}
const mapStateToProps = state => {
return {
auth: state.auth
}
}
const mapDispatchToProps = dispatch => {
return {
login: (email, passwd) => dispatch(ActionCreator.signinRequest(email,passwd)),
reset: () => dispatch(ActionCreator.resetError())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ScreensLogin)
Have some problem don't using the tag ?
You are using controlled component.
remove onclick from the button
<button type="button" className="button button2 " onClick={() => this.login()}>logar</button>
to
<button type="button" className="button button2">logar</button>
and in your form
<form onSubmit={this.login}>
this way you are actually submitting the form,
on other side you can pass event in button like this
<button type="button" className="button button2 " onClick={(e) => this.login(e)}>logar</button>
and in login function
login = (e) => {
e.preventDefault();
const {email, passwd} = this.state.form
this.props.login(email, passwd)
}
This way you can tell the form that I have handled submission of the form you do not need to do anything.

Categories