I receive error 400 after changing from Class component to Functional Component - javascript

It was working a while ago, the searchBar component was a class component and I tried to change it to a functional component but suddenly I receive error 400. I tried to create a new youtube API but it keeps showing.
is it because of api?
Here is my App.js
import { Grid } from '#material-ui/core'
import React, { useState } from 'react'
import youtube from './api/youtube'
import { SearchBar, VideoDetail, VideoList } from './components'
const App = () => {
const [videos, setVideo] = useState([])
const [selectdvideo, setSelectedVideo] = useState(null)
const onFormSubmit = async (value) => {
const response = await youtube.get('search', {
params: {
part: 'snippet',
maxResults: 5,
key: '',
q: value,
},
})
console.log('hello')
setVideo(response.data.items)
setSelectedVideo(response.data.items[0])
}
return (
<Grid justifyContent="center" container spacing={10}>
<Grid item xs={12}>
<Grid container spacing={10}>
<Grid item xs={12}>
<SearchBar onFormSubmit={onFormSubmit} />
</Grid>
<Grid item xs={8}>
<VideoDetail video={selectdvideo} />
</Grid>
<Grid item xs={4}>
<VideoList videos={videos} onSelectVideo={setSelectedVideo} />
</Grid>
</Grid>
</Grid>
</Grid>
)
}
export default App
This is the searchBar
import { Paper, TextField } from '#material-ui/core'
import React, { useState } from 'react'
const SearchBar = ({ onFormSubmit }) => {
const [searchTerm, setSearchTerm] = useState('')
const handleChange = (event) => setSearchTerm(event.target.value)
const onKeyPress = (event) => {
if (event.key === 'Enter') {
onFormSubmit(searchTerm)
}
}
return (
<Paper elavtion={6} style={{ padding: '25px' }}>
<TextField
fullWidth
label="Search..."
value={searchTerm}
onChange={handleChange}
onKeyPress={onKeyPress}
/>
</Paper>
)
}
export default SearchBar
[enter image description here][1]
I receive this error
https://ibb.co/Vpz9nKG

Related

Send selected text to another div in react JS using onSelect event?

I have a two div I want to send selected text to another div using onSelect event? Right now entire para sending to another div but I want to send just selected text. How can I do this?
Demo:- https://codesandbox.io/s/selected-text-send-to-another-div-using-onselect-0ccnrn?file=/src/App.js
My Code:-
import React from "react";
import { Box, Grid, TextField, Typography } from "#material-ui/core";
import { useState } from "react";
const SendSelectedText = () => {
const [label1, setlabel1]=useState('');
const [para, setPara]=useState('This is Old Para');
const handleClick = () => {
setlabel1(para);
};
return (
<>
<Box className="sendSelectedTextPage">
<Grid container spacing={3}>
<Grid item xl={6} lg={6} md={6}>
<textarea onSelect={handleClick}>{para}</textarea>
</Grid>
<Grid item xl={6} lg={6} md={6}>
<TextField
variant="outlined"
size="small"
label="Label One"
value={label1}
multiline
rows={3}
className="sendSelectedTextPageInput"
/>
</Grid>
</Grid>
</Box>
</>
);
};
export default SendSelectedText;
Thanks for your support!
All you need is use window.getSelection().
Here is solution
import React from "react";
import { Box, Grid, TextField, Typography } from "#material-ui/core";
import { useState } from "react";
const SendSelectedText = () => {
const [label1, setlabel1] = useState("");
const [para, setPara] = useState("This is Old Para");
const handleMouseUp = () => {
setlabel1(window.getSelection().toString()); // setting up label1 value
};
return (
<>
<Box className="sendSelectedTextPage">
<Grid container spacing={3}>
<Grid item xl={6} lg={6} md={6}>
// changed event to onMouseUp
<textarea onMouseUp={handleMouseUp}>{para}</textarea>
</Grid>
<Grid item xl={6} lg={6} md={6}>
<TextField
variant="outlined"
size="small"
label="Label One"
value={label1}
multiline
rows={3}
className="sendSelectedTextPageInput"
/>
</Grid>
</Grid>
</Box>
</>
);
};
export default SendSelectedText;
Sandboxlink
You have to use the selection
const handleClick = (e) => {
setlabel1(
e.target.value.substring(e.target.selectionStart, e.target.selectionEnd)
);
};
or
const handleClick = (e) => {
setlabel1(
para.substring(e.target.selectionStart, e.target.selectionEnd)
);
};
Based on this
sandbox

How to pass data from input field to parent component using context API in React?

I have an input field in child component. If you type in valid wallet address it should display wallet balance in parent component.
I don't know how to pass that e.target.value we are reading from input field.
I tried to do this function in parent component - Dashboard.
const [walletBalance, setWalletBalance] = useState('');
const getWalletBalance = async () => {
try {
const web3 = new Web3(Web3.givenProvider || 'ws://localhost:3000');
for (const wallet of dummyWallets) {
const balance = await web3.eth.getBalance(wallet.address);
console.log(balance);
const balanceConvertedFromWeiToEth = await Web3.utils.fromWei(balance, 'ether');
const shortenedBalance =
balanceConvertedFromWeiToEth.length >= 10
? balanceConvertedFromWeiToEth.slice(0, 10)
: balanceConvertedFromWeiToEth;
setWalletBalance(shortenedBalance);
}
} catch (error) {
console.error(error);
throw new Error('No wallet found');
}
};
render (
<p>Wallet balance: {walletBalance}</p>
and then pass this function down to child component with input field (need to prop drill 3 times for that) and in child component say:
const [inputText, setInputText] = useState('');
const handleInputChange = (e) => {
setInputText(e.target.value);
if (inputText === wallet.address) {
getWalletBalance()
}
};
render (
<input value={inputText} onChange={handleInputChange} />
)
It didn't work. No errors. Just nothing happens.
Then I thought that I need to do the other way around: Instead of trying to pass getWalletBalance() down as props, I need to read data from input field and pass that data to parent component, because parent needs to have access to the input field and read from it to be able to display wallet balance in parent.
I've also tried to create context:
import React, { useState, createContext } from 'react';
import { dummyWallets } from '../mocks/dummyWallets';
import Web3 from 'web3';
export const WalletContext = createContext();
// eslint-disable-next-line react/prop-types
export const TransactionProvider = ({ children }) => {
const [inputText, setInputText] = useState('');
const [walletBalance, setWalletBalance] = useState('');
const handleInputChange = async (e) => {
setInputText(e.target.value);
const web3 = new Web3(Web3.givenProvider || 'ws://localhost:3000');
for (const wallet of dummyWallets) {
if (inputText === wallet.address) {
const balance = await web3.eth.getBalance(wallet.address);
console.log(balance);
const balanceConvertedFromWeiToEth = await Web3.utils.fromWei(balance, 'ether');
const shortenedBalance =
balanceConvertedFromWeiToEth.length >= 10
? balanceConvertedFromWeiToEth.slice(0, 10)
: balanceConvertedFromWeiToEth;
setWalletBalance(shortenedBalance);
}
}
};
return (
<WalletContext.Provider
value={{ walletBalance, handleInputChange, inputText, setInputText,
setWalletBalance }}>
{children}
</WalletContext.Provider>
);
};
Then pass handleInputChange to onChange in child component and inputText as value, then use walletBalance in parent component.
All context things walletBalance, handleInputChange, inputText, setInputText and setWalletBalance threw undefined error.
Here is child component consuming data from context:
import React, { FC, useState, useContext } from 'react';
import { Formik, Form, Field } from 'formik';
import { Button, InputAdornment, Box, Grid } from '#material-ui/core';
import TextField from '#eyblockchain/ey-ui/core/TextField';
import { Search } from '#material-ui/icons';
import SvgEthereum from '../../../images/icon/Ethereum';
import { makeStyles } from '#material-ui/styles';
import { Theme } from '#material-ui/core';
import { dummyWallets } from '../../../shared/mocks/dummyWallets';
import Web3 from 'web3';
import { WalletContext } from '../../../shared/context/WalletContext';
const etherIconBorderColor = '#eaeaf2';
const useStyles = makeStyles((theme: Theme) => ({
etherIconGridStyle: {
padding: '16px 0 0 0'
},
etherIconStyle: {
fontSize: '220%',
textAlign: 'center',
color: theme.palette.primary.light,
borderTop: `solid 1px ${etherIconBorderColor}`,
borderBottom: `solid 1px ${etherIconBorderColor}`,
borderLeft: `solid 1px ${etherIconBorderColor}`,
padding: '5px 0 0 0',
[theme.breakpoints.down('sm')]: {
fontSize: '150%',
lineHeight: '43px'
}
},
buttonStyle: {
paddingTop: theme.spacing(2)
},
searchIconStyle: {
color: theme.palette.primary.light
}
}));
const onSubmitHandler = () => {
return;
};
const SearchInputForm: FC<any> = (props) => {
const { walletBalance, handleInputChange, inputText } = useContext(WalletContext);
const classes = useStyles();
return (
<Formik
onSubmit={onSubmitHandler}
initialValues={{ name: '' }}
render={({ values }) => {
return (
<Form>
<Grid container>
<Grid item xs={1} className={classes.etherIconGridStyle}>
<Box className={classes.etherIconStyle}>
<SvgEthereum />
</Box>
</Grid>
<Grid item xs={11}>
<Field
required
name="name"
placeholder={props.placeholdervalue}
value={inputText}
component={TextField}
onChange={handleInputChange}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<Search fontSize="large" className={classes.searchIconStyle} />
</InputAdornment>
)
}}
/>
</Grid>
<Grid item xs={12}>
<Box
display="flex"
justifyContent="flex-end"
alignItems="flex-end"
className={classes.buttonStyle}>
<Button type="submit" variant="contained" color="secondary" size="large" disabled>
Create Alert
</Button>
</Box>
</Grid>
</Grid>
</Form>
);
}}
/>
);
};
export default SearchInputForm;
Here is parent component where I pull walletBalance from context:
const Dashboard: FC<any> = () => {
const { walletBalance } = useContext(WalletContext);
const classes = useStyles();
return (
<>
<Container maxWidth={false} className={classes.dashboardContainer}>
<Grid>
<Box data-testid="alert-page-heading">
<Typography variant="h3">Alerts</Typography>
</Box>
<Box data-testid="alert-page-subheading">
<Typography className={classes.subHeadingStyle}>
Monitor the Web 3.0 for interesting blockchain events
</Typography>
</Box>
</Grid>
<Grid container spacing={4}>
<Grid item xs={12} sm={8}>
<Box className={classes.dashboardCard}>
<Box className={classes.searchBox}>
<SearchTabs />
</Box>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between'
}}>
<Box
sx={{
height: '60%',
padding: '1%',
fontSize: 20
}}>
<a href="http://localhost:3000/" className={classes.backToAlertsLink}>
Back to my alerts
</a>
<p className={classes.boldText}>Recent transactions</p>
</Box>
<Box sx={{ height: '60%', padding: '4%', fontSize: 20 }}>
<span>Wallet Balance</span>
<span className={classes.balanceNumber}>{walletBalance} ETH</span>
</Box>
</Box>
</Box>
</Grid>
<Grid item xs={12} sm={4}>
<Box className={classes.dashboardCard}>
<Box sx={{ height: '60%', padding: '2%', fontSize: 20, fontWeight: 'bold' }}>
Top 10 alerts
</Box>
</Box>
</Grid>
</Grid>
</Container>
</>
);
};
export default Dashboard;
The problem is that I pull handleChange from context and apply to input field in child component to read the value from the input and then pull walletBalance from context in parent but that walletBalance is not updated (doesn't contain input value in it).
Can someone please share knowledge on how to read data from child component input field and display something from that in parent component?
Any advice is appreciated. Thank you.

React Router history.push in infinite loop

I have a page ("/paymentsucess"). In this page, I am using the react-countdown-circle-timer component (https://github.com/vydimitrov/react-countdown-circle-timer#props-for-both-reactreact-native). Upon reaching this page ("/paymentsuccess"), countdown beings. After countdown reaches zero, I want to redirect user back to home page ("/").
To achieve this, for the CountdownCircleTimer component, when onComplete, I set the state initialMount to false.
<CountdownCircleTimer
onComplete={() => {
setInitialMount(false);
return [true, 1500];
}}
isPlaying
duration={2}
colors={[
["#004777", 0.33],
["#F7B801", 0.33],
["#A30000", 0.33],
]}
>
{renderTime}
</CountdownCircleTimer>
Given that initialMount is changed, my useEffect (in the paymentsuccess component) will kick in and redirect users to "/". I am using history.push("/") here.
useEffect(() => {
if (initialMount !== true) {
console.log("On change in status,");
console.log(initialMount);
history.push("/");
}
}, [initialMount, history]);
I was able to redirect user back to "/" successfully. But upon reaching "/", they got redirected back to /paymentsuccess again. And then from /paymentsuccess it goes back to / and then the loops continue. Infinite loop.
Any idea what I am doing wrong here? :( I need to stop this loop and lands user back to / and stops there.
I am using Router from react-router-dom and createBrowserHistory from history.
Below is the full code for my paymentsuccess component
import React, { useEffect, useStatem} from "react";
import { useHistory } from "react-router-dom";
import { makeStyles } from "#material-ui/core/styles";
import Grid from "#material-ui/core/Grid";
import Paper from "#material-ui/core/Paper";
import { CountdownCircleTimer } from "react-countdown-circle-timer";
function PaymentSuccess() {
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
}));
const classes = useStyles();
const history = useHistory();
const [initialMount, setInitialMount] = useState(true);
useEffect(() => {
console.log("On component mount, status is");
console.log(initialMount);
}, []);
useEffect(() => {
return () => {
console.log("On component unmount, status is");
setInitialMount(true);
console.log(initialMount);
};
}, []);
useEffect(() => {
if (initialMount !== true) {
console.log("On change in status,");
console.log(initialMount);
history.push("/");
}
}, [initialMount, history]);
const renderTime = ({ remainingTime }) => {
if (remainingTime === 0) {
return <div className="timer">Starting...</div>;
}
return (
<div className="timer">
<div className="value">{remainingTime}</div>
</div>
);
};
return (
<div className={classes.root}>
<Grid container spacing={0}>
<Grid item xs={6} sm={6}>
<Paper
className="paymentSuccessLeftPaper"
variant="outlined"
square
></Paper>
</Grid>
<Grid item xs={6} sm={6}>
<Paper className="paymentSuccessRightPaper" variant="outlined" square>
<h1>Payment Success</h1>
<CountdownCircleTimer
onComplete={() => {
setInitialMount(false);
return [true, 1500];
}}
isPlaying
duration={2}
colors={[
["#004777", 0.33],
["#F7B801", 0.33],
["#A30000", 0.33],
]}
>
{renderTime}
</CountdownCircleTimer>
</Paper>
</Grid>
</Grid>
</div>
);
}
export default PaymentSuccess;
I have checked my "/" page and I don't think there is any logic there redirecting to "/paymentsuccess". The page ("/") code is as below.
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Grid from "#material-ui/core/Grid";
import Paper from "#material-ui/core/Paper";
import Button from "#material-ui/core/Button";
import Link from "#material-ui/core/Link";
function LandingPage() {
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
paper: {
minHeight: "100%",
padding: theme.spacing(0),
textAlign: "center",
color: theme.palette.text.secondary,
},
}));
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={0}>
<Grid item xs={4} sm={4}>
<Paper className={classes.paper} variant="outlined" square>
<h1>Photo Strips</h1>
<Button variant="contained" color="primary">
<Link href="/photo10">SELECT</Link>
</Button>
</Paper>
</Grid>
<Grid item xs={4} sm={4}>
<Paper className={classes.paper} variant="outlined" square>
<h1>Photo Strips and GIF</h1>
<Button variant="contained" color="primary">
<Link href="/photogif12">
SELECT
</Link>
</Button>
</Paper>
</Grid>
<Grid item xs={4} sm={4}>
<Paper className={classes.paper} variant="outlined" square>
<h1>Photo Strips and Boomerang</h1>
<Button variant="contained" color="primary">
<Link href="/photoboomerang12">
SELECT
</Link>
</Button>
</Paper>
</Grid>
</Grid>
</div>
);
}
export default LandingPage;
Thank you all in advance! Appreciate all the help and advise
UPDATE
Below is Router code
import React from "react";
import { Router, Switch } from "react-router-dom";
import LandingPage from "./components/LandingPage";
import Photo10 from "./components/Photo10";
import PhotoGIF12 from "./components/PhotoGIF12";
import PhotoBoomerang12 from "./components/PhotoBoomerang12";
import PaymentSuccess from "./components/PaymentSuccess";
import DynamicLayout from "./router/DynamicLayout";
import { history } from "./helpers/history";
const App = () => {
return (
<Router history={history}>
<div className="App">
<Switch>
<DynamicLayout
exact
path="/"
component={LandingPage}
layout="LANDING_NAV"
/>
<DynamicLayout
exact
path="/photo10"
component={Photo10}
layout="PHOTO10_PAGE"
/>
<DynamicLayout
exact
path="/photogif12"
component={PhotoGIF12}
layout="PHOTOGIF12_PAGE"
/>
<DynamicLayout
exact
path="/photoboomerang12"
component={PhotoBoomerang12}
layout="PHOTOBOOMERANG12_PAGE"
/>
<DynamicLayout
exact
path="/paymentsuccess"
component={PaymentSuccess}
layout="PAYMENTSUCCESS_PAGE"
/>
</Switch>
</div>
</Router>
);
};
export default App;
Below is the code for the DynamicLayout component
import React from "react";
const DynamicLayout = (props) => {
const { component: RoutedComponent, layout } = props;
const actualRouteComponent = <RoutedComponent {...props} />;
switch (layout) {
case "LANDING_NAV": {
return <>{actualRouteComponent}</>;
}
case "PHOTO10_PAGE": {
return <>{actualRouteComponent}</>;
}
case "PHOTOGIF12_PAGE": {
return <>{actualRouteComponent}</>;
}
case "PHOTOBOOMERANG12_PAGE": {
return <>{actualRouteComponent}</>;
}
case "PAYMENTSUCCESS_PAGE": {
return <>{actualRouteComponent}</>;
}
default: {
return (
<>
<h2>Default Nav</h2>
{actualRouteComponent}
</>
);
}
}
};
export default DynamicLayout;
This problem occurs when you changes value of variable in useEffect and that variable also added in useEffect dependency array, So when ever your useEffect change the value due to presence of that variable in dependency array, it again called the useEffect thus a infinite loop occurs
so just remove 'history' variable from your dependency array

Issue in react context api

Facing issues in react context api, getting undefined while transferring anything using context api.
getting this error, getting undefined when sending functions through context api.
*** Context.js
import React, { useReducer, createContext } from "react";
import contextReducer from "./contextReducer";
const initialState = [];
export const ExpenseTrackerContext = createContext(initialState);
export function Provider({ children }) {
const [transactions, dispatch] = useReducer(contextReducer, initialState);`enter code here`
const deleteTransaction = (id) =>
dispatch({ type: "DELETE_TRANSACTION", payload: id });
const addTransaction = (transaction) =>
dispatch({ type: "ADD_TRANSACTION", payload: transaction });
return (
<ExpenseTrackerContext.Provider
value={{
deleteTransaction,
addTransaction,
transactions,
}}
>
{children}
</ExpenseTrackerContext.Provider>
);
}***
getting undefined in this file while using the function in this file Form.js > and getting error addTransaction is not a function
*** Form.js
import React, { useState, useContext } from "react";
import {
TextField,
Typography,
Grid,
FormControl,
InputLabel,
Select,
MenuItem,
Button,
} from "#material-ui/core";
import { ExpenseTrackerContext } from "../../context/context";
import { v4 as uuidv4 } from "uuid";
import useStyles from "./styles";
const initialState = {
amount: "",
category: "",
type: "Income",
date: new Date(),
};
const Form = (props) => {
const classes = useStyles();
const [formData, setFormData] = useState(initialState);
// console.log(useContext(ExpenseTrackerContext));
const { addTransaction } = useContext(ExpenseTrackerContext);
console.log("context: " + ExpenseTrackerContext.displayName);
console.log("add: " + typeof addTransaction);
const createTransaction = () => {
const transaction = {
...formData,
amount: Number(formData.amount),
id: uuidv4(),
};
addTransaction(transaction);
setFormData(initialState);
};
return (
<Grid container spacing={2}>
<Grid item xs={12}>
<Typography align="center" variant="subtitle2" gutterBottom>
...
</Typography>
</Grid>
<Grid item xs={6}>
<FormControl fullWidth>
<InputLabel>Type</InputLabel>
<Select
value={formData.type}
onChange={(e) => setFormData({ ...formData, type: e.target.value })}
>
<MenuItem value="Income">Income</MenuItem>
<MenuItem value="Expense">Expense</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={6}>
<FormControl fullWidth>
<InputLabel>Category</InputLabel>
<Select
value={formData.category}
onChange={(e) =>
setFormData({ ...formData, category: e.target.value })
}
>
<MenuItem value="business">Business</MenuItem>
<MenuItem value="Salary">Salary</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={6}>
<TextField
type="number"
label="Amount"
fullWidth
value={formData.amount}
onChange={(e) => setFormData({ ...formData, amount: e.target.value })}
/>
</Grid>
<Grid item xs={6}>
<TextField
type="date"
label=" "
fullWidth
value={formData.date}
onChange={(e) => setFormData({ ...formData, date: e.target.value })}
/>
</Grid>
<Button
className={classes.button}
variant="outlined"
color="primary"
fullWidth
onClick={createTransaction}
>
Create
</Button>
</Grid>
);
};
export default Form; ***
why?
you are forget to call the context with in From.js. Because you are created the context hook with same page
Better create the context file seperate js file
context.js
import React,{createContext} from 'react';
export const ExpenseTrackerContext = createContext(null);
Contextr.js
import {ExpenseTrackerContext} from './context.js' // path of context.js
From.js
import React,{useContext} from 'react';
import {ExpenseTrackerContext} from './context.js' // path of context.js
export default function From(props){
const expContext = useContext(ExpenseTrackerContext);
expContext.addTransaction()// you could call like this
...
Updated - React Doc
Accepts a context object (the value returned from React.createContext)
and returns the current context value for that context. The current
context value is determined by the value prop of the nearest
<MyContext.Provider> above the calling component in the tree.
Context passing value only with in tree of children. please check Form.js is execute inside the {children} component of context provider. if you are using parallel or sibling component its does not work
<ExpenseTrackerContext.Provider
value={{
deleteTransaction,
addTransaction,
transactions,
}}
>
{children} // From.js present in this children in any one of the tree otherwise undefined (value only passed inside the provider component tree)
</ExpenseTrackerContext.Provider>

Why does react app reload after file save in my project?

Hello iI have a project in react + graphql + node and mongod, and iI tried to upload images to a folder in my app and i have a problem with the reload of app after the file save. I tried to manage a local state in the component when performing the upload process, but my local variable changed to the initial state because of a reload app, and cant it does not show a preview of my file. My goal is show a preview of img upload.
I think my problem is in the resolver, in the function storeUpload
Code.
API-----------Resolver------
const Product = require('../models/Product');
const { createWriteStream } = require("fs");
async function createProduct(root, args) {
console.log(args.file)
let product = await new Product(args)
console.log(product);
product.save()
if(args.file){
const { stream, filename, mimetype, encoding } = await args.file;
await storeUpload({ stream, product });
}
return product
}
const storeUpload = ({ stream, product }) =>
new Promise((resolve, reject) =>
stream
.pipe(createWriteStream("./images/" + product._id +".png"))
.on("finish", () => resolve())
.on("error", reject)
);
module.exports = {
createProduct
}
---React--- Component----
import React , { useState, useEffect } from 'react'
import {Grid} from '#material-ui/core'
import { Mutation } from "react-apollo"
import {PRODUCTOS} from './Productos'
import gql from "graphql-tag";
import {StyleStateConsumer} from '../../../Context/StylesStateContext'
/** #jsx jsx */
import { jsx, css } from '#emotion/core'
const borde = css({
borderStyle: 'solid'
})
const contendorForm = css({
borderRadius: 15,
backgroundColor: '#ffffe6'
},borde)
const itemsForm = css({
padding: 15
})
const inputStyle = css({
borderRadius: 5,
padding: 3
})
const ADD_PRODUCT = gql`
mutation CreateProduct($title: String, $price: Float, $file: Upload) {
createProduct(title: $title, price: $price, file: $file) {
_id
title
}
}
`;
const CrearProducto = props =>{
const [titleInput, settitleInput] = useState('')
const [priceInput, setpriceInput] = useState(0)
const [fileInput, setfileInput] = useState('')
const [imgName, setimgName] = useState('default')
const handleChange = e =>{
const {name, type, value} = e.target
if(name === 'titleInput'){settitleInput(value)}
if(name === 'priceInput'){setpriceInput(parseFloat(value))}
}
const imgUpdate = (imgConxt) => {
setimgName(imgConxt)
}
useEffect( imgUpdate )
const handleFile = (obj) =>{console.log(obj)}
return(
<StyleStateConsumer>
{({imagenID, updateHState})=>(
<Grid container css={borde}
direction="row"
justify="center"
alignItems="center">
<Grid item css={contendorForm}>
{imgUpdate(imagenID)}
<Grid container
direction="row"
justify="center"
alignItems="center"><Grid item >Crear Producto:</Grid>
</Grid>
<Grid container>
<Mutation mutation={ADD_PRODUCT} refetchQueries={[{
query: PRODUCTOS
}]}>
{(createProduct, { data, loading })=>{
if (loading) return <div>Loading...</div>
console.log(data)
return(
<div>
<form css={itemsForm}
onSubmit={ (e) => {
e.preventDefault()
createProduct({
variables: {
title: titleInput,
price: priceInput,
file: fileInput
}
})
//
updateHState(res.data.createProduct._id
=== undefined ? '' :
res.data.createProduct._id)
settitleInput('')
setpriceInput(0)
//
console.log(res.data.createProduct._id)
}}>
<Grid item>
<input
css={inputStyle}
type="file"
onChange={({
target: { validity, files:
[file] } }) => validity.valid &&
setfileInput(file)
}
/>
</Grid>
<Grid item>
<label>
Titulo:
</label>
</Grid>
<Grid item>
<input css={inputStyle} type="text"
name="titleInput"
placeholder="Ingresar Título"
value={titleInput}
onChange={handleChange}
/>
</Grid>
<Grid item>
<label>
Precio:
</label>
</Grid>
<Grid item>
<input css={inputStyle} type="number"
name="priceInput"
placeholder="Ingresar Precio"
value={priceInput}
onChange={handleChange}/>
</Grid>
<Grid item>
<input type="submit" name="Crear"/>
</Grid>
</form>
</div>
)
}}
</Mutation>
</Grid>
</Grid>
<Grid item css={[borde,
{
backgroundImage: `url('${require('../../../../../back-
end/images/' + imgName + '.png')}')`,
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
height: 300,
width: 300}]}>
</Grid>
</Grid>
)}
</StyleStateConsumer>
)
}
export default CrearProducto
Well, first the imgUpdate function you're passing to useEffect won't ever get its imgConxt parameter. This hook just calls an empty-parameter function to execute a bunch of code after render.
For your main problem, do you have any warnings or errors in the console ?
One quick but dirty fix would be to change your <input type='submit'> to type button and do your logic in an onClick handler there.

Categories

Resources