Modal reseting the redux state - javascript

I made a react/redux application using firebase, but when i open the modal and close it or add a product all data of application are set hidden
App.js file
import React, { useState } from "react";
import "./App.css";
import Layout from "./components/Layout/Layout";
import Header from "./components/Header/Header";
import FormModal from "./components/Modal/FormModal";
import Modal from "./components/Modal/Modal";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import thunk from "redux-thunk";
import ProductReducer from "./reducers/ProductReaducer";
import Card from "./components/Card/Card";
function App() {
const store = createStore(ProductReducer);
const [showModal, setShowModal] = useState(false);
const onShowModal = () => {
setShowModal(true);
};
const onHideModal = () => {
setShowModal(false);
};
return (
<div>
<Provider store={store}>
<Header onShowModal={onShowModal} />
<Layout>
<Card />
</Layout>
<Modal show={showModal}>
<FormModal show={showModal} onHideModal={onHideModal} />
</Modal>
</Provider>
</div>
);
}
export default App;
Modal.js file
import React from "react";
import { useSelector } from "react-redux";
const Modal = (props) => {
const states = useSelector((state) => state);
console.log(states);
return (
<div
className={
props.show
? `bg-slate-400 fixed top-0 left-0 w-screen h-screen flex justify-center items-center z-1`
: "hidden"
}
>
{props.children}
</div>
);
};
export default Modal;
FormModal.js file
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { addItem } from "../../actions/ProductActions";
import { collection, addDoc, getFirestore } from "firebase/firestore";
const FormModal = (props) => {
const [infoProduct, setInfoProduct] = useState({
title: "",
url: "",
description: "",
price: 0,
});
const handleChange = (evt) => {
const targetValue = evt.target.value;
const key = evt.target.name;
setInfoProduct((old) => ({
...old,
[key]: targetValue,
}));
};
const dispatch = useDispatch();
const db = getFirestore();
const addProduct = async () => {
try {
const docRef = await addDoc(collection(db, "webjump-store"), productItem);
dispatch(addItem(infoProduct));
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
};
const productItem = {
produto: {
title: infoProduct.title,
url: infoProduct.url,
description: infoProduct.description,
price: infoProduct.price,
},
};
return (
<div className={props.show ? "bg-slate-300 w-64 p-6 z-1" : "hidden"}>
{" "}
<button type="button" className="float-right" onClick={props.onHideModal}>
X
</button>
<form className="flex flex-col items-center">
<label>Title</label>
<input
className="my-3"
type="text"
name="title"
onChange={handleChange}
/>
<label>Url</label>
<input
className="my-3"
type="text"
name="url"
onChange={handleChange}
/>
<label>Description</label>
<input
className="my-3"
type="text"
name="description"
onChange={handleChange}
/>
<label>Price</label>
<input
className="my-3"
type="text"
name="price"
onChange={handleChange}
/>
<button
className="my-4 p-4 bg-slate-200 border-2 border-solid border-black"
type="button"
onClick={addProduct}
>
Add Product
</button>
</form>
</div>
);
};
export default FormModal;
I have no ideia o it can be.
When i do a console.log in my redux state it appers to be empty.
But when i reload the page all data from fire store appears again.

Related

How to used React-transliterate in div contentEditable custom Component

How can add React Transliterate in div contentEditable.. Please help me
import './App.css';
import EditText from "./component/EditText"
import Tools from "./component/tools"
import Header from "./component/header"
import Img from "./component/img"
import './scss/style.scss';
import MyImage from './home.png';
import React, { useState } from "react";
import { ReactTransliterate, Language } from "react-transliterate";
const App = () => {
const [text, setText] = useState("");
const [message, setMessage] = useState('');
const handleKeyDown = event => {
console.log(event.key);
if (event.key === 'Enter') {
event.preventDefault();
console.log(message);
console.log(event.target.value)
console.log('User pressed Enter ');
}
};
// const [lang, setLang] = useState<Language>("hi");
return (
<div className="App">
<Header/>
<div className='App_leftbar'>
<ul>
<li>
<a href='#'><img src={MyImage} /></a>
</li>
</ul>
</div>
<div className='App_centerbar'>
<div
contentEditable="true"
id="message"
name="message"
value={text}
onChange={event => setText(event.target.value)}
onKeyDown={handleKeyDown}
/>
<ReactTransliterate
renderComponent={(props) => <EditText onChange={event => setText(event.target.value)}
onKeyDown={handleKeyDown} {...props} />}
value={text}
onChangeText={(text) => {
setText(text);
}}
lang="hi"
placeholder="Start typing here..."
id="react-transliterate-input"
/>
<Img src={MyImage}/>
</div>
<div className='App_rightbar'>
<Tools />
</div>
</div>
);
}
export default App;
I used this npm https://www.npmjs.com/package/react-transliterate?activeTab=readme
import React, { useState } from "react";
import { ReactTransliterate } from "react-transliterate";
import "react-transliterate/dist/index.css";
const App = () => {
const [text, setText] = useState("");
return (
<ReactTransliterate
value={text}
onChangeText={(text) => {
setText(text);
}}
lang="hi"
/>
);
};
export default App;
React Transliterate uses the event.keycode property to detect keys. Here are some predefined keys you can use. Or, you can enter the integer codes for any other key you'd like to use as the trigger

React giving a blank white page on rendering the Chat component, after integrating firebase for messages

I am creating a chat app. The app returns a blank page after the login page, instead of showing the chat section. The problem is with the firebase code which I used for getting the messages from the firebase database. If I don't render the Chat section, then the Sidebar section turns out to render well. The Chat component code is:
import React, { useEffect, useState } from "react";
import "./Chat.css";
import { Avatar, IconButton } from "#material-ui/core";
import { SearchOutlined } from "#material-ui/icons";
import { AttachFile } from "#material-ui/icons";
import MoreVertIcon from "#material-ui/icons/MoreVert";
import MicIcon from "#material-ui/icons/Mic";
import InsetEmoticonIcon from "#material-ui/icons/InsertEmoticon";
import { useParams } from "react-router-dom";
import db from "./firebase";
function Chat() {
const [input, setInput] = useState("");
const [photo, setphoto] = useState("");
const [messages, setMessages] = useState();
const { roomId } = useParams();
const [roomName, setRoomName] = useState();
useEffect(() => {
if (roomId) {
console.log("Change");
db.collection("rooms")
.doc(roomId)
.onSnapshot((snapshot) => setRoomName(snapshot.data().name));
db.collection("rooms")
.doc(roomId)
.collection("messages")
.orderBy("timestamp", "asc")
.onSnapshot((snapshot) =>
setMessages(snapshot.docs.map((doc) => doc.data()))
);
}
}, [roomId]);
useEffect(() => {
setphoto(Math.floor(Math.random() * 5000));
}, []);
const sendMessage = (e) => {
e.preventDefault();
console.log("You typed a message");
setInput("");
};
return (
<div className="chat">
<div className="chat-header">
<Avatar
src={`https://avatars.dicebear.com/api/pixel-art/${photo}.svg`}
/>
<div className="chat-headerInfo">
<h2>{roomName}</h2>
<p>Last Seen</p>
</div>
<div className="chat-headerRight">
<IconButton>
<SearchOutlined />
</IconButton>
<IconButton>
<AttachFile />
</IconButton>
<IconButton>
<MoreVertIcon />
</IconButton>
</div>
</div>
<div className="chat-body">
{messages.map((message) => (
<p className="chat-message chatReceiver">
<span className="sender">{message.name}</span>
{message.message}
<span className="timestamp">
{new Date(message.timestamp?.toDate()).toUTCString}
</span>
</p>
))}
</div>
<div className="chat-footer">
<InsetEmoticonIcon />
<form>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
type="text"
placeholder="Type a message"
/>
<button onClick={sendMessage} type="submit">
Send a message
</button>
</form>
<MicIcon />
</div>
</div>
);
}
export default Chat;
Github link of the project : https://github.com/aditramdas/Chat-App/tree/main/chat-app-new/src

REACT Why do I get the error "Uncaught TypeError: createTask is not a function" when calling a function passed as a parameter?

I am getting this error when passing a function as props to a component. But I can't figure out what's going on. Thanks in advance
TaskForm
import { useState } from "react";
function TaskForm(createTask) {
const [title, setTitle] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
const newTask = {
title,
};
createTask(newTask);
};
return (
<form onSubmit={handleSubmit}>
<input
placeholder="Escribe tu tarea"
onChange={(e) => setTitle(e.target.value)}
/>
<button>Guardar</button>
</form>
);
}
export default TaskForm;
App
import TaskList from "./TaskList";
import TaskForm from "./TaskForm";
import { tasks as data } from "./tasks";
import { useState, useEffect } from "react";
function App() {
const [tasks, setTasks] = useState([]);
useEffect(() => {
setTasks(data);
}, []);
function createTask(task) {
setTasks([...tasks, task]);
}
return (
<>
<TaskForm createTask={createTask} />
<TaskList tasks={tasks} />
</>
);
}
export default App;
Try to get data from props via destructuring as we are getting props as object
import {useState} from 'react'
function TaskForm({ createTask }) {
const [title, setTitle] = useState('');
const handleSubmit = (e) =>{
e.preventDefault();
const newTask = {
title
};
createTask(newTask)
}
return (
<form onSubmit={handleSubmit}>
<input placeholder="Escribe tu tarea"
onChange={(e)=> setTitle(e.target.value)}
/>
<button>
Guardar
</button>
</form>
)
}
or you can try as:
import {useState} from 'react'
function TaskForm(props) {
const { createTask } = props;
const [title, setTitle] = useState('');
const handleSubmit = (e) =>{
e.preventDefault();
const newTask = {
title
};
createTask(newTask)
}
return (
<form onSubmit={handleSubmit}>
<input placeholder="Escribe tu tarea"
onChange={(e)=> setTitle(e.target.value)}
/>
<button>
Guardar
</button>
</form>
)
}
App.js
import { useState } from "react";
import TaskForm from "./component/Comp1";
import TaskList from "./component/Comp2";
import "./styles.css";
export default function App() {
const [tasks, setTasks] = useState([]);
const creteTask = (newTasks) => {
setTasks([...tasks, newTasks]);
};
return (
<div className="App">
<TaskForm creteTask={creteTask} />
<TaskList tasks={tasks} />
</div>
);
}
TaskForm.js
import { useState } from "react";
export default function TaskForm({ creteTask }) {
const [title, setTitle] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
creteTask(title);
setTitle("");
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
placeholder="Escribe tu tarea"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<button>Guardar</button>
</form>
</div>
);
}
TaskList.js
export default function TaskList({ tasks }) {
console.log(tasks);
return (
<div>
<h3>Tasks</h3>
{tasks.map((task, i) => (
<p key={i}>{task}</p>
))}
</div>
);
}

React Redux - app/store resets after added item to store

I cant figure out why when I add an item to my store the app resets. I can see for a split second that its being added to my list but then I can see all my component flicker and reload. Inspecting the console doesn't bring up any warnings.
I also plugged in just my addProduct component and productsSlice into the redux template and it also reloaded the app.
Basic HTML for adding a product with hooks:
import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
import { addProduct } from '../_reducers/productsSlice'
const AddProduct = () => {
const [title, setTitle] = useState('');
const [description, setDescription] = useState('')
const [price, setPrice] = useState('')
const onTitleChanged = e => setTitle(e.target.value);
const onDescriptionChanged = e => setDescription(e.target.value);
const onPriceChanged = e => setPrice(e.target.value);
const dispatch = useDispatch();
return (
<section>
<h2>Add a new Product</h2>
<form>
<label htmlFor="Title">Title</label>
<input
type="text"
name="title"
value={title}
onChange={onTitleChanged} />
<label htmlFor="Price">Price</label>
<input
type="text"
value={price}
onChange={onPriceChanged} />
<label htmlFor="Description">Description</label>
<textarea
value={description}
onChange={onDescriptionChanged} />
<button onClick={() => dispatch(addProduct({
title: title,
price: price,
description: description
}))}>
Submit
</button>
</form>
</section>
)
}
export default AddProduct;
My Reducer:
import { createSlice } from '#reduxjs/toolkit'
const initialProductsState = [
// { name: '1', price: 10, description: 'testDescrip1' },
// { name: '2', price: 20, description: 'testDescrip2' },
// { name: '3', price: 30, description: 'testDescrip3' },
{ name: '4', price: 40, description: 'testDescrip4' }]
export const productsSlice = createSlice({
name: 'products',
initialState: initialProductsState,
reducers: {
addProduct: (state, action) => {
state.push(action.payload)
},
}
})
export const { addProduct } = productsSlice.actions;
export default productsSlice.reducer
Listing of the products:
import React from 'react';
import { useSelector } from 'react-redux'
import { Row, Col } from 'react-bootstrap'
import ProductItem from "./ProductItem"
const ProductList = () => {
const products = useSelector(state => state.products)
let numberRendered = 3;
const renderedProducts = products.map(item => (
<ProductItem product={item} />
))
return (
<div id="ProductList">
<Row>
<Col>
{renderedProducts}
</Col>
</Row>
</div>
)
}
export default ProductList;
And the product component styled with react-bootstrap:
import React from 'react';
import {productSlice} from '../_reducers/productsSlice';
import { Card, Col, Row } from 'react-bootstrap'
const ProductItem = (props) => {
return (
<Card>
<Card.Body>
<Row>
<Col md={4}>
<Card.Img variant="float" src={process.env.PUBLIC_URL + 'placeholder.png'} />
</Col>
<Col md={8}>
<Card.Title>{props.product.title}</Card.Title>
<Card.Text>{props.product.description}</Card.Text>
<Card.Subtitle>{props.product.price}</Card.Subtitle>
</Col>
</Row>
</Card.Body>
</Card>
)
}
export default ProductItem;
store:
import { configureStore } from '#reduxjs/toolkit'
import productsSlice from '../src/_reducers/productsSlice'
const store = configureStore({
reducer: {
products: productsSlice,
}
})
export default store;
Pretty sure you just need to add an event.preventDefault() to the form's submit event
import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
import { addProduct } from '../_reducers/productsSlice'
const AddProduct = () => {
const [title, setTitle] = useState('');
const [description, setDescription] = useState('')
const [price, setPrice] = useState('')
const onTitleChanged = e => setTitle(e.target.value);
const onDescriptionChanged = e => setDescription(e.target.value);
const onPriceChanged = e => setPrice(e.target.value);
const dispatch = useDispatch();
const handleSubmit = (e) => {
e.preventDefault();
dispatch(addProduct({
title: title,
price: price,
description: description
}))
}
return (
<section>
<h2>Add a new Product</h2>
<form onSubmit={handleSubmit}>
<label htmlFor="Title">Title</label>
<input
type="text"
name="title"
value={title}
onChange={onTitleChanged} />
<label htmlFor="Price">Price</label>
<input
type="text"
value={price}
onChange={onPriceChanged} />
<label htmlFor="Description">Description</label>
<textarea
value={description}
onChange={onDescriptionChanged} />
<button type="submit">
Submit
</button>
</form>
</section>
)
}
export default AddProduct;
Without the preventDefault submitting the form will submit a get request to the same route, which will cause the component to reload.

Call function from material ui fonction

I want to pass a function as a props to my material ui function.
The given function is undefined in my material ui fonction.
import React, { Component } from 'react';
import styled from 'styled-components';
import InputBase from '#material-ui/core/InputBase';
import IconButton from '#material-ui/core/IconButton';
import Menu from '#material-ui/core/Menu';
import MenuItem from '#material-ui/core/MenuItem';
import SearchIcon from '#material-ui/icons/Search';
import Avatar from '#material-ui/core/Avatar';
import '../../css/App.css';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { withTranslation } from 'react-i18next';
import CreateNewGarden from './CreateNewGarden';
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
};
this.myFunction = this.myFunction.bind(this);
}
myFunction() {
console.log("OK")
}
render() {
return (
<div>
<CreateNewGarden myFunction={this.myFunction}/>
</div>
);
}
}
const mapStateToProps = (state) => ({
});
Dashboard.propTypes = {
};
export default withTranslation()(withRouter(connect(mapStateToProps)(Dashboard)));
I send CreateNewGarden myFunction={this.myFunction} as a props and in my others file.
I have:
import React from 'react';
import { withStyles } from '#material-ui/core/styles';
import Dialog from '#material-ui/core/Dialog';
import MuiDialogTitle from '#material-ui/core/DialogTitle';
import MuiDialogContent from '#material-ui/core/DialogContent';
import MuiDialogActions from '#material-ui/core/DialogActions';
import IconButton from '#material-ui/core/IconButton';
import CloseIcon from '#material-ui/icons/Close';
import Typography from '#material-ui/core/Typography';
import Slider from '#material-ui/core/Slider';
import { useTranslation } from 'react-i18next';
import measureLogo from '../../assets/images/measure.png';
import { Button } from '../../components';
const styles = (theme) => ({
root: {
margin: 0,
padding: theme.spacing(2),
},
closeButton: {
position: 'absolute',
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500],
}
});
const DialogTitle = withStyles(styles)((props) => {
const {
children, classes, onClose, ...other
} = props;
return (
<MuiDialogTitle disableTypography className={classes.root} {...other}>
<Typography variant="h6">{children}</Typography>
{onClose ? (
<IconButton aria-label="close" className={classes.closeButton} onClick={onClose}>
<CloseIcon />
</IconButton>
) : null}
</MuiDialogTitle>
);
});
const DialogContent = withStyles((theme) => ({
root: {
padding: theme.spacing(2)
}
}))(MuiDialogContent);
const DialogActions = withStyles((theme) => ({
root: {
margin: 0,
padding: theme.spacing(1)
}
}))(MuiDialogActions);
export default function CustomizedDialogs(props) {
const [open, setOpen] = React.useState(false);
// eslint-disable-next-line no-unused-vars
const [height, setHeight] = React.useState(0);
// eslint-disable-next-line no-unused-vars
const [width, setWidth] = React.useState(0);
console.log("ici = " + props.myFunction)
const setSizeHeight = () => (e, value) => {
setHeight(value);
};
const setSizeWidth = () => (e, value) => {
setWidth(value);
};
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const { t } = useTranslation();
return (
<div className="marginCardComponent">
<Button
onClick={handleClickOpen}
text="dashboard.createGardenBtn"
type="submit"
/>
<Dialog onClose={handleClose} aria-labelledby="customized-dialog-title" open={open}>
<DialogTitle id="customized-dialog-title" className="centerText" onClose={handleClose}>
{t('dashboard.createGardenTitle')}
</DialogTitle>
<DialogContent className="logoMeasureParent">
<img src={measureLogo} alt="Logo" className="logoMeasure centerText" />
</DialogContent>
<DialogContent dividers>
<Typography className="centerText" gutterBottom>
{ t('dashboard.createGardenDetail') }
</Typography>
</DialogContent>
<div className="marginLeft3">
<p>{ t('dashboard.height') }</p>
</div>
<div className="centerSlider">
<Slider
/* eslint-disable-next-line react/destructuring-assignment */
defaultValue={0}
aria-labelledby="discrete-slider"
valueLabelDisplay="auto"
step={1}
marks
min={1}
max={20}
onChange={setSizeHeight()}
/>
</div>
<div className="marginLeft3">
<p>{ t('dashboard.width') }</p>
</div>
<div className="centerSlider">
<Slider
/* eslint-disable-next-line react/destructuring-assignment */
defaultValue={0}
aria-labelledby="discrete-slider"
valueLabelDisplay="auto"
step={1}
marks
min={1}
max={20}
onChange={setSizeWidth()}
/>
</div>
<DialogActions>
<Button
onClick={handleClose}
text="dashboard.cancelBtn"
type="submit"
/>
<Button
onClick={props.myFunction}
text="dashboard.createGardenBtn"
type="submit"
/>
</DialogActions>
</Dialog>
</div>
);
}
When i click on the button it does nothing and when i print myFunction it tell me undefined.
Why i can't give a props to the function and call myFunction ?
Thank you for your help.
You need to call it outside of onClick. Do it like this:
const handleClick = (e) => {
e.preventDefault()
props.myFunction()
}
And in the button:
<Button
onClick={handleClick}
text="dashboard.createGardenBtn"
type="submit"
/>
That will work. It just isnt letting you call it inside onClick
You can also just do this:
<Button
onClick={() => props.myFunction()}
text="dashboard.createGardenBtn"
type="submit"
/>

Categories

Resources