I have the following problem, I have a function but after a few seconds or minutes it runs on its own without clicking.
If someone can help me that I am failing, when I click the function works fine but after a few seconds or minutes it executes itself
Thank you
there I leave the code
import React, { useContext, Fragment, useState,useEffect} from 'react';
import clienteAxios from '../../config/axios';
import { withRouter } from 'react-router-dom';
import { CRMContext } from '../../context/CRMContext';
const ListadoPedidos =(props) => {
const [ auth, setAuth ] = useContext(CRMContext);
const [pedidos, setPedidos] = useState([]);
const detallePedido = id => {
props.history.push(`/detalle-pedido/${id}`);
}
const eliminarPedido = () => {
}
useEffect( () => {
if(auth.token !== '') {
//query a la API
const consultarAPI = async () => {
try {
const pedidosConsulta = await clienteAxios.get(`/pedidoscliente/${auth.clienteId}`);
setPedidos(pedidosConsulta.data);
} catch (error) {
if(error.response.status === 500) {
props.history.push('/iniciar-sesion');
}
}
}
consultarAPI();
} else {
props.history.push('/iniciar-sesion');
}
}, [] );
return(
<Fragment>
<div class="row justify-content-end">
<button type="button"
class="btn btn-dark mr-2"
onClick={() => detallePedido(pedido.id)}
>
Ver detalle</button>
</div>
</Fragment>
)
}
export default withRouter(ListadoPedidos);
Related
I have problem with fetching data when language changed. I tried a lot of things that I found from Stack overflow, but unfortunately it just changing the direction and it didn't fetch the data based on language changed.
I fetching data with a custom hook and call it inside my functional component. let me share the code that I write.
Note: I'm using I18nextLng for translation.
App.js
import { RouterProvider } from "react-router-dom";
import Loading from './components/loading';
import routes from './routes/routes';
import { useEffect } from "react";
import i18n from "./utils/i18n";
function App() {
useEffect(() => {
let cleanup = true;
if (cleanup) {
i18n.on('languageChanged', (local) => {
let direction = i18n.dir(local);
document.body.dir = direction;
})
}
return () => {
cleanup = false;
};
}, []);
return (
<RouterProvider router={routes} fallbackElement={<Loading />} />
)
}
export default App;
LanguageSwitcher.js
import { useTranslation } from "react-i18next";
const LanguageSwitcher = () => {
const { i18n } = useTranslation();
return (
<select
className="form-select-sm rounded-pill text-center"
aria-label="Default select example"
value={i18n.language}
onChange={(e) =>
i18n.changeLanguage( e.target.value)
}
>
<option value="en">English</option>
<option value="fa">دری</option>
</select>
);
}
export default LanguageSwitcher;
Internships.js
import Image from "react-bootstrap/Image"
import { useFetchWebsiteData } from "../../hooks/website/useFetchWebsiteData";
import Loading from '../../components/loading'
import { useEffect, useState } from "react";
const Internships = () => {
let lang = localStorage.getItem("i18nextLng")
const { data, isLoading } = useFetchWebsiteData("getInternship", lang);
console.log("language changed", language);
return !isLoading ? (
<div className="container-fluid news-wrapper">
<div className="container">
<div className="row py-5">
<div className="col-md-12">
<div className="col-md-8">
<h4 className="title mb-4">{data?.title}</h4>
<p className="sub-title">{data?.content}</p>
</div>
<div className="col-md-2 text-center">
<Image
src={require("../../images/internships.png")}
fluid={true}
/>
</div>
</div>
</div>
</div>
</div>
) : (
<Loading />
);
}
export default Internships;
useFetchWebsiteData.js (Custom hook for fetching data)
import { useState, useEffect } from "react";
import { axiosPublic } from "../../utils/axios";
export const useFetchWebsiteData = (url,lang) => {
const [data, setData] = useState({});
const [isLoading, setIsLoading] = useState(true);
const [isError, setIsError] = useState(false);
// const lang = localStorage.getItem("i18nextLng");
console.log('lang inside hook', lang)
useEffect(() => {
// const controller = new AbortController()
const fetchData = async () => {
setIsLoading(true);
await axiosPublic
.get(url, {
headers: { lang: lang === "fa" ? "dr" : "en" },
// signal: controller.signal,
})
.then((response) => {
if (response.status === 200) {
if (lang === "en") {
setIsLoading(false);
response.data.data.en.map((d) => {
let title = d.title;
let content = d.content;
return setData({ title: title, content: content });
});
}
if (lang === "fa") {
setIsLoading(false);
console.log("fa intern", response.data.data.dr)
response.data.data.dr.map((d) => {
let title = d.title;
let content = d.content;
return setData({ title: title, content: content });
});
setIsLoading(false);
}
} else {
setIsError(true);
}
})
.catch((error) => {
setIsLoading(false);
setIsError(true);
console.error(error.message);
});
};
fetchData();
// return () => {
// controller.abort()
// };
}, [url, lang]);
return { data, isLoading, isError };
};
I really appreciate for your helping.
I'm trying to make a sport/tinder like app for a school project from a friend of mine. It came together well on my localhost, but for him it was a requirement to host it online. Not really a professional in hosting, but I was a bit familiar with Heroku. I used a client and a server side for my application, so I build the client side and put it into the server side folder. This server side is hosted on the Heroku page. But whenever I try to login, it won't work and I get this error message in my console.
TypeError: Cannot read properties of undefined (reading 'map')
The error says it is caused by this line of code.
const matchedUserIds = matches.map(({user_id}) => user_id)
This is the whole MatchDisplay file that is used in my Dashboard. I'm using a MongoDB for the storage of my users.
import axios from "axios";
import { useEffect, useState } from "react";
import { useCookies } from "react-cookie";
const MatchesDisplay = ({ matches, setClickedUser }) => {
const [matchedProfiles, setMatchedProfiles] = useState(null);
const [cookies, setCookie, removeCookie] = useCookies(null);
const [matched, setMatched] = useState(null);
const matchedUserIds = matches.map(({ user_id }) => user_id);
const userId = cookies.UserId;
const getMatches = async () => {
try {
const response = await axios.get(
"https://[app].herokuapp.com/users",
{
params: { userIds: JSON.stringify(matched()) },
}
);
setMatchedProfiles(response.data);
} catch (error) {
console.log(error);
}
};
useEffect(() => {
getMatches();
}, [matches]);
const filteredMatchedProfiles = matchedProfiles?.filter(
(matchedProfile) =>
matchedProfile.matches.filter(
(profile) => profile.user_id === userId
).length > 0
);
return (
<div className="matches-display">
{filteredMatchedProfiles?.map((match) => (
<div
key={match.user_id}
className="match-card"
onClick={() => setClickedUser(match)}
>
<div className="img-container">
<img
src={match?.url}
alt={match?.first_name + "profile"}
/>
</div>
<h3>{match?.first_name}</h3>
</div>
))}
</div>
);
};
export default MatchesDisplay;
Any help is welcome. If you need more code examples, please reply ;)
EDIT
The ChatContainer that passes the user to the MatchesDisplay.
import ChatHeader from "./ChatHeader";
import MatchesDisplay from "./MatchesDisplay";
import ChatDisplay from "./ChatDisplay";
import { useState } from 'react';
const ChatContainer = ({user}) => {
const [ clickedUser, setClickedUser] = useState(null)
return (
<div className="chat-container">
<ChatHeader user={user}/>
<div>
<button className="option" onClick={() => setClickedUser(null)}>Matches</button>
<button className="option" disabled={!clickedUser}>Chat</button>
<button className="option" >Prices</button>
</div>
{!clickedUser && <MatchesDisplay matches={user.matches} setClickedUser={setClickedUser}/>}
{clickedUser && <ChatDisplay user={user} clickedUser={clickedUser}/>}
</div>
)
}
export default ChatContainer
The Dashboard that passes the user to the Chatcontainer.
import TinderCard from 'react-tinder-card';
import {useEffect, useState} from 'react';
import {useCookies} from 'react-cookie';
import ChatContainer from '../components/ChatContainer'
import axios from "axios";
const Dashboard = () => {
const [user, setUser] = useState(null)
const [genderedUsers, setGenderedUsers] = useState(null)
const [lastDirection, setLastDirection] = useState(null)
const [cookies, setCookie, removeCookie] = useCookies(['user'])
const [matchedUserIds, setMatchedUserIds] = useState(null)
const [filteredGenderedUsers, setFilteredGenderedUsers] = useState(null)
const userId = cookies.UserId
const getUser = async () => {
try {
const response = await axios.get('https://funfit-webpage.herokuapp.com/user', {
params: {userId}
})
return setUser(response.data)
} catch (error) {
console.log(error)
}
}
const getGenderedUsers = async () => {
try {
const response = await axios.get('https://funfit-webpage.herokuapp.com/gendered-users', {
params: {gender: user?.gender_interest}
})
return setGenderedUsers(response.data)
} catch (error) {
console.log(error)
}
}
useEffect(() => {
getUser()
}, [])
useEffect(() => {
setMatchedUserIds(user?.matches.map(({user_id}) => user_id).concat(userId))
if (user) return getGenderedUsers()
}, [user])
useEffect(() => {
if (genderedUsers) {
return setFilteredGenderedUsers(genderedUsers?.filter(
genderedUser => !matchedUserIds.includes(genderedUser.user_id)
))
}
}, [genderedUsers])
const updateMatches = async (matchedUserId) => {
try {
await axios.put('https://funfit-webpage.herokuapp.com/addmatch', {
userId,
matchedUserId
})
return getUser()
} catch (error) {
console.log(error)
}
}
const swiped = (direction, swipedUserId) => {
console.log(direction, swipedUserId)
if (direction === 'right') {
updateMatches(swipedUserId)
}
return setLastDirection(direction)
}
const outOfFrame = (name) => {
console.log(name + ' left the screen!')
}
return (<>
{user && <div className="dashboard">
<ChatContainer user={user}/>
<div className="swipe-container">
<div className="card-container">
{filteredGenderedUsers?.map((genderedUser) =>
<TinderCard
className='swipe'
key={genderedUser.user_id}
onSwipe={(dir) => swiped(dir, genderedUser.user_id)}
onCardLeftScreen={() => outOfFrame(genderedUser.first_name)}>
<div style={{backgroundImage: 'url(' + genderedUser.url + ')'}} className='card'>
<h3>{'Name: ' + genderedUser.first_name} <br/> {'Sport: ' + genderedUser.about}</h3>
</div>
</TinderCard>)}
<div className="swipe-info">
{lastDirection ? <p>You swiped {lastDirection}</p> : <p/>}
</div>
</div>
</div>
</div>}
</>)
}
export default Dashboard
I am displaying a foto in the front using Leigh Halliday's Image Previews in React with FileReader from https://www.youtube.com/watch?v=BPUgM1Ig4Po and everything is super BUT:
1.I want to get information from the image is displaying, exactly the base64 info, and have it then globally in my reactjs app.
2.for that reason I made a Context, i configured it ok BUT:
when I am doing dispatch inside a useEffect I want the image rendering and the info store in my variable globally
but I have one thing or another
if my image renders ok in my front, I can not obtain the value of my dispatch and viceversa
this is the code of my component:
import React, { useContext, useEffect, useRef, useState } from 'react'
import { AuthContext } from '../../auth/AuthContext'
import { types } from '../../types/types'
export const ButtonLoadFoto = () => {
const { dispatchFoto } = useContext(AuthContext)
const [image, setImage] = useState('')
const [preview, setPreview] = useState('')
const [status, setStatus] = useState(false)
useEffect(() => {
if (image) {
const reader = new FileReader()
reader.onloadend = () => {
setPreview(reader.result)
}
reader.readAsDataURL(image)
setStatus(true)
} else {
setPreview('')
}
}, [image])
// useEffect(() => {
// if (status) {
// dispatchFoto({
// type: types.foto,
// payload: {
// foto: preview.split(',')[1]
// }
// })
// }
// return () => setStatus(false)
// }, [preview])
const fileInputRef = useRef()
const handleRef = (e) => {
e.preventDefault()
fileInputRef.current.click()
}
const handleFile = (e) => {
const file = e.target.files[0]
if (file && file.type.substr(0, 5) === 'image') {
setImage(file)
}
}
return (
<div className='load-input '>
{
preview
?
(<img src={preview} alt='' onClick={() => setImage('')} />)
:
(<button
className='alert alert-danger'
onClick={handleRef}>
foto
</button>
)
}
< input
type='file'
style={{ display: 'none' }}
ref={fileInputRef}
accept='image/*'
onChange={handleFile}
/>
</div>
)
}
in the code above if you put away the comments we will have the information we want but the foto won t display at all
thanks all for your time , I really appreciate!
EDIT
this is the main component
import React, { useEffect, useReducer } from 'react'
import { AuthContext } from './auth/AuthContext'
import { fotoReducer } from './components/formScreen/fotoReducer'
import { AppRouter } from './routers/AppRouter'
const initImage = () => {
return { foto: '' }
}
export const CMI = () => {
const [foto, dispatchFoto] = useReducer(fotoReducer, {}, initImage)
return (
<div>
<AuthContext.Provider value={{
foto,
dispatchFoto
}}>
<AppRouter />
</AuthContext.Provider>
</div>
)
}
this is the componenent I use
import React, { useContext} from 'react'
import { ButtonLoadFoto } from '../components/formScreen/ButtonLoadFoto'
import { AuthContext } from '../auth/AuthContext'
export const FormScreen = () => {
const { foto } = useContext(AuthContext)
}
return (
<div>
<ButtonLoadFoto/>
</div>
)
as I said : if a render the image I can not have the information and viceversa...
when I use dispatch I don t know I it brokes the image render
thanks in advance
I am reading image data from firebase storage and getting the URLs of the images in an array.
I console logged the array. It is fine.
I made a variable of img elements through map() function on that array.
That variable is also fine.
But I am not able to render more than one in the component. Only the last image tag renders from the array.
import React, { useRef, useState, useEffect } from 'react'
import { Card, Button, Alert } from 'react-bootstrap'
import { Link, useHistory } from 'react-router-dom'
import { UseAuth } from '../context/AuthContex'
import app from './../firebase'
import { db } from './../firebase'
import './Dashboard.css'
function Dashboard() {
const [error, setError] = useState('')
const { currentUser, logout } = UseAuth()
const history = useHistory()
const picURLS = []
const [photo, setPhoto] = useState()
async function getPics() {
const DBRef = db.collection('pics');
const snapshot = await DBRef.where('author', '==', currentUser.uid).get();
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
snapshot.forEach(doc => {
var storage = app.storage();
var gsReference = storage.refFromURL('<bucket address>' + doc.data().filename)
gsReference.getDownloadURL().then(function (url) {
picURLS.push(url);
}).catch(function (error) {
console.log(error)
});
});
}
useEffect(() => {
getPics()
console.log('getPIcs() triggered.')
console.log(picURLS)
setPhoto(picURLS.map(postdata => (
<img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />)))
console.log(photo)
}, [])
return (
<div>
<div>{photo}</div>
<div className="menu pmd-floating-action" role="navigation">
<Link to='/upload-pic' className="pmd-floating-action-btn btn pmd-btn-fab pmd-btn-raised pmd-ripple-effect btn-primary" data-title="Splash New Image?" href="javascript:void(0);">
<span className="pmd-floating-hidden">Primary</span>
<i className="material-icons pmd-sm">add</i>
</Link>
</div>
</div>
)
}
export default Dashboard
It would be better to add picURLS to your state variables because useEffect runs only once with empty dependencies array and setPhoto(picURLS.map) surely would work with an empty picURLS array before it will be filled. So your photo var surely would be empty. You should call your map in the render function;
{picURLS.map(postdata => (
<img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />))}
Try this code
import React, { useRef, useState, useEffect } from 'react'
import { Card, Button, Alert } from 'react-bootstrap'
import { Link, useHistory } from 'react-router-dom'
import { UseAuth } from '../context/AuthContex'
import app from './../firebase'
import { db } from './../firebase'
import './Dashboard.css'
function Dashboard() {
const [error, setError] = useState('')
const { currentUser, logout } = UseAuth()
const history = useHistory()
const [picURLS, setPicURLS] = useState([])
async function getPics() {
const DBRef = db.collection('pics');
const snapshot = await DBRef.where('author', '==', currentUser.uid).get();
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
const newUrls = [];
snapshot.forEach(doc => {
var storage = app.storage();
var gsReference = storage.refFromURL('<bucket address>' + doc.data().filename)
gsReference.getDownloadURL().then(function (url) {
newUrls.push(url);
}).catch(function (error) {
console.log(error)
});
});
setPicURLS(newUrls);
}
useEffect(() => {
getPics()
console.log('getPIcs() triggered.')
console.log(picURLS)
}, [])
return (
<div>
<div>{
picURLS.map(postdata => (
<img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />))}
</div>
<div className="menu pmd-floating-action" role="navigation">
<Link to='/upload-pic' className="pmd-floating-action-btn btn pmd-btn-fab pmd-btn-raised pmd-ripple-effect btn-primary" data-title="Splash New Image?" href="javascript:void(0);">
<span className="pmd-floating-hidden">Primary</span>
<i className="material-icons pmd-sm">add</i>
</Link>
</div>
</div>
)
}
export default Dashboard
photo is array of React components. you need to loop over photo using map array method again to show in render.
{photo.map((img) => { img }}
I useMutation to send message ,but the message list in chat window not change. I found that the cache has changed . Please help , I can't understand.
The useQuery not work . UI have no change :(
But~! When I put them in one js file. it works.... why???
The version I used is #apollo/react-hooks 3.1.1
Parent window.js
import React from 'react';
import { useQuery } from "#apollo/react-hooks";
import { GET_CHAT } from "#/apollo/graphql";
import ChatInput from "#/pages/chat/components/input";
const ChatWindow = (props) => {
const { chatId, closeChat } = props;
const { data, loading, error } = useQuery(GET_CHAT, { variables: { chatId: chatId } });
if (loading) return <p>Loading...</p>;
if (error) return <p>{error.message}</p>;
const { chat } = data;
return (
<div className="chatWindow" key={'chatWindow' + chatId}>
<div className="header">
<span>{chat.users[1].username}</span>
<button className="close" onClick={() => closeChat(chatId)}>X</button>
</div>
<div className="messages">
{chat.messages.map((message, j) =>
<div key={'message' + message.id} className={'message ' + (message.user.id > 1 ? 'left' : 'right')}>
{message.text}
</div>
)}
</div>
<div className="input">
<ChatInput chatId={chatId}/>
</div>
</div>
);
};
export default ChatWindow;
Child input.js
import React, { useState } from 'react';
import { useApolloClient, useMutation } from "#apollo/react-hooks";
import { ADD_MESSAGE, GET_CHAT } from "#/apollo/graphql";
const ChatInput = (props) => {
const [textInput, setTextInput] = useState('');
const client = useApolloClient();
const { chatId } = props;
const [addMessage] = useMutation(ADD_MESSAGE, {
update(cache, { data: { addMessage } }) {
const { chat } = client.readQuery({
query: GET_CHAT,
variables: {
chatId: chatId
}
});
chat.messages.push(addMessage);
client.writeQuery({
query: GET_CHAT,
variables: {
chatId: chatId
},
data: {
chat
}
});
}
});
const onChangeInput = (event) => {
event.preventDefault();
setTextInput(event.target.value);
};
const handleKeyPress = (event, chatId, addMessage) => {
if (event.key === 'Enter' && textInput.length) {
addMessage({
variables: {
message: {
text: textInput,
chatId: chatId
}
}
});
setTextInput('');
}
};
return (
<input type="text"
value={textInput}
onChange={(event) => onChangeInput(event)}
onKeyPress={(event) => handleKeyPress(event, chatId, addMessage)}
/>
);
};
export default ChatInput;
You probably solved the issue by now, but for the record:
Your code mutates the chat state:
chat.messages.push(addMessage);
State should not be mutated (see the React setState Docs for more details).
Contruct a new array instead:
const newChat = [...chat, addMessage]