How do I add a post route to my react application - javascript

I have a modal with the following code in my components and I would like to add a post route to my code to capture the user's response. I have Mongo/Mongoose set up as well as a backend server. Any help would be amazing as I am new to React!
render() {
return(
<div className="modal column y-center">
<h3>How are you doing?</h3>
{!this.state.start ? (
<div className="choices">
<button onClick={() => this.startRelaxation('ok_images')}>Ok</button>
<button onClick={() => this.startRelaxation('neutral_images')}>Neutral</button>
<button onClick={() => this.startRelaxation('anxious_images')}>Anxious</button>
</div>
) : (
<div className="column y-center">
<div className="image">
<img src={this.state[this.state.mood][this.state.current_image]}/>
</div>
<button onClick={this.nextImage.bind(this)}>Next Image</button>
</div>
)}
<button onClick={this.props.closeModal}>Close</button>
</div>
)
}
}

I would recommend hooking up your startRelaxation() function to execute a HTTP request to your backend using a 3rd party library such as Axios.
Alternatively, given you are using MongoDB, you may find a database management tool such as Parse Server very useful.

This is just building off of Arman's post, but you can do something like this:
import axios from 'axios';
import React, {Component} from 'react';
class YouComponent extends Component {
constructor(props){
super(props);
this.startRelaxation = this.startRelaxation.bind(this);
}
startRelaxation(string){
axios.post('YourRoute'{'BODY OF REQUEST'})
.then(data => 'DO STUFF WITH DATA');
}
render() {
return(
<div className="modal column y-center">
<h3>How are you doing?</h3>
{!this.state.start ? (
<div className="choices">
<button onClick={() => this.startRelaxation('ok_images')}>Ok</button>
<button onClick={() => this.startRelaxation('neutral_images')}>Neutral</button>
<button onClick={() => this.startRelaxation('anxious_images')}>Anxious</button>
</div>
) : (
<div className="column y-center">
<div className="image">
<img src={this.state[this.state.mood][this.state.current_image]}/>
</div>
<button onClick={this.nextImage.bind(this)}>Next Image</button>
</div>
)}
<button onClick={this.props.closeModal}>Close</button>
</div>
)
}
}
You have the axios request in the startRelation method and you can do whatever you need to do in the DB.

Related

Passing data between child components in React

My goal is to use an onClick function in one of my components, and pass that data to another component (end goal is that in the other component called Playlist, it updates an array with the id of the clicked item).
I am just not sure how to pass the information between child components
My main component (app.jsx) looks like this
const mainCards = Data.map(card => {
return(
<MainCard
key={card.id}
id={card.id}
image={card.url}
title={card.title}
playbutton={card.playbutton}
addbutton={card.addbutton}
/>
)
})
const sideCards = SideData.map(card => {
return(
<SideCard
image={card.sideurl}
key={card.id}
title={card.sidetitle}
playbutton={card.playbutton}
addbutton={card.addbutton}
/>
)
})
return (
<div className="App">
<Navbar />
<Header />
<Playlist />
<CardContainer />
<div className="maincards">
{mainCards}
</div>
<div className="sidecards">
{sideCards}
</div>
</div>
)
}
export default App
The component where I am using onClick (MainCard.jsx)
const handleAdd = (id) => {
console.log(id)
}
return(
<div className="mainCardObject">
<div className="cardObj">
<img src={props.image} className ="mainCardImage"/>
<img src={props.playbutton} className="playbutton"/>
<img src={props.addbutton} onClick={() => handleAdd(props.id)} className="addbutton" />
</div>
</div>
)
}
export default MainCard
and the component I wish to pass information to (nothing inside, as I dont know where to start)
return(
<div className="playlistContainer">
<ul>
<li></li>
</ul>
</div>
)
}
export default Playlist```
My suggestion is that you manage 'ids array' state globally creating a context, using the hook useContext(). Here a link with a simple explanation. I hope it helps!
https://www.w3schools.com/react/react_usecontext.asp

Toggle between two components /buttons using react toggle hook {Show one component and Hide another}

I'm trying to create a Job platform, Where we can Sign up/login as either "Recruiter" or as a "Candidate". The complication I'm facing is I've created a form for both recruiter and candidate. Now I'm trying to switch between those componets. I've come this far
import useToggle from "#rooks/use-toggle"
export default function SignUp() {
const [recruitForm, setRecruitForm] = useToggle(true);
const [candidateForm, setCandidateForm] = useToggle(false);
}
return (
<div>
<form>
<div className="text-md tracking-wide p-0">
SignUp Form
</div>
<div className="flex flex-row gap-8">
<div>
<button
onClick={setRecruitForm}>
Recruiter
</button>
<>
{recruitForm && <RecruiterForm /> }
</>
</div>
<div>
<button
onClick={setCandidateForm}
type="button">
Candidate
</button>
<>
{candidateForm && <CandidateForm /> }
</>
</div>
</div>
</form>
</div>
</div>
)
}
Components are within their own context. But I have trouble even coming up with an idea how to handle or switch components without messing up the styling, the way it needs to be is when one instance opens, close the other conundrum / Form.
I'm sharing the output I've got using the useToggle react rooks
Any ideas on how to achieve it with any other hook or with useToggle hook itself or please let me know what I'm doing wrong.
https://www.loom.com/share/d2251bc3b9594782aa0a17aae92c997e {This is the result I've got}
Since thay are two Items you can make use of a boolean and just one state
const [active, setActive] = useState(false)
return (
<div>
<form>
<div className="text-md tracking-wide p-0">
SignUp Form
</div>
<div className="flex flex-row gap-8">
<div>
<button
onClick={()=>setActive(true)}>
Recruiter
</button>
<>
{active && <RecruiterForm /> }
</>
</div>
<div>
<button
onClick={()=>setActive(false)}
type="button">
Candidate
</button>
<>
{!active && <CandidateForm /> }
</>
</div>
</div>
</form>
</div>
</div>
)
}
as far as I can understand from your question, that you have created 2 from components for recruiter and candidate and want to show either on of em at a time. If not please do comment, I'll rectify the answer.
instead of checking your toggles when you will be rendering components, do before that, also you only need one toggle for this, better use a use state.
The initial false state for recruiter and true candidate
import React, {useState} from 'react';
export default function SignUp() {
const [switchForm, setSwitchForm] = useState(false);
return (
<div>
<form>
<div className="text-md tracking-wide p-0">
SignUp Form
</div>
<div className="flex flex-row gap-8">
<button
onClick={setSwitchForm(false)}>
Recruiter
</button>
<button
onClick={setSwitchForm(true)}
type="button">
Candidate
</button>
</div>
<div className="flex flex-row gap-8">
<>
{switchForm ? <CandidateForm /> : <RecruiterForm />}
</>
</div>
</form>
</div>
</div>
)};
This is not the actual/accurate code but just to give you the logical idea.
Also just a suggestion, use a custom hook for your parent component (signup.jsx) and put hooks there and import it from their to parent component and may come in use when you are going to submit the forms so that the states
and handler functions can have a common place to share.

how to use DOM element in React

I want to do getElementById to give css effect and click to slide function.
how do I use DOM in react? Thank you in advance.
function Auth() {
//this part needs to be fixed
const signUpButton = document.getElementById('signUp');
const signInButton = document.getElementById('signIn');
const container = document.getElementById('body');
signUpButton.addEventListener('click', () =>
container.classList.add('right-panel-active'));
signInButton.addEventListener('click', () =>
container.classList.remove('right-panel-active'));
Here are the classnames that might help you understand my code better.
return (
<div className ="auth">
<div className="body" id="body">
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button className="slide__btn" id='signUp' > Sign In </button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button className="slide__btn" id='signIn' > Sign Up </button>
</div>
</div>
</div>
</div>
</div>
)
}
I guess the propose to use React is that fact you should interact in the component state.
I suggest you use State in your component and add some according to some interaction
function App() {
const [mode, setMode] = React.useState();
const handleMode = (mode) => {
setMode(mode);
};
const containerClasses =
mode === "signUp" ? "body right-panel-active" : "body";
return (
<div className="auth">
<div className={containerClasses} id="body">
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button
className="slide__btn"
id="signUp"
onClick={() => handleMode("signIn")}
>
{" "}
Sign In{" "}
</button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button
className="slide__btn"
id="signIn"
onClick={() => handleMode("signUp")}
>
{" "}
Sign Up{" "}
</button>
</div>
</div>
</div>
</div>
</div>
);
}
You should avoid direct modification of the dom in React. React assumes that it is the only piece of code modifying the dom, and so it won't know about any changes you make. This opens up the possibility of bugs where react changes something on the dom that you don't expect, or doesn't change something you do expect. A simple piece of code like yours won't have these bugs, but best to learn the react way now so you don't run into these issues with more complicated code.
The react way to do this is to pass onClick props to the elements that need it, and to have a state variable which controls the class names. For example:
import React, { useState } from 'react';
function Auth() {
const [showPanel, setShowPanel] = useState(false);
return (
<div className="auth">
<div className={showPanel ? "body right-panel-active" : "body"}>
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button
className="slide__btn"
onClick={() => setShowPanel(false)}
>
Sign In
</button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button
className="slide__btn"
onClick={() => setShowPanel(true)}
>
Sign Up
</button>
</div>
</div>
</div>
</div>
</div>
);
}

how to show specific post details by clicking using react-router-parameters?

I'm using map to view all posts using axios. And I just want show when I click a specific post to see more information. I'm using react parameters. But it's not working.
Here is my one component
import React, {Component} from 'react';
import Album from './album'
import {Link, BrowserRouter as Router, Route} from 'react-router-dom'
import axios from "axios"
class ViewDataAPI extends Component{
state = {
posts: []
}
componentDidMount(){
axios.get('https://jsonplaceholder.typicode.com/comments')
.then(response => {
this.setState({
posts: response.data
})
})
.catch(error => console.log('error'))
}
render(){
let { posts } = this.state
if(posts.length === 0){
return <h1>Loading...</h1>
}
else{
return(
<Router>
<div className="header">
<div className="container">
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="text-center mb-20">
<h1>View Data From API</h1>
<p>using jsx-component, props, state, map in react </p>
</div>
</div>
</div>
<div className="row">
{
posts.map(post =>
{
return (
<Album
key={post.id}
name={post.name}
email = {post.email}
body = {post.body}
view = {post.id}
/>
)
}
)
}
</div>
{/* here is im using params, and to match by clicking specific id to show/view more information */}
<div className="row">
{posts && (
<Route path="/album/:albumId"
render = {({match}) => (
<ViewPosts {...posts.find(pv => pv.id === match.params.albumId)} />
)}
/>
)}
</div>
</div>
</div>
</Router>
)
}
}
}
export default ViewDataAPI;
// This component using for show details
const ViewPosts = ({posts}) =>{
return(
<div className="col-lg-6">
<div className="card border-dark mb-3">
<div className="card-body text-dark">
<div className="album">
<h3>{posts.name}</h3>
<h3>{posts.email}</h3>
<Link to="./">Back To Home</Link>
</div>
</div>
</div>
</div>
);
}
This is album component that has a link
import React, {Component} from 'react'
import {Link} from "react-router-dom"
class Album extends Component{
render(){
return(
<div className="col-lg-6">
<div className="card border-dark mb-3">
<div className="card-body text-dark">
<div className="album">
<h3>{this.props.name}</h3>
<p>{this.props.email}</p>
<p>{this.props.body}</p>
<Link to={`/album/${this.props.view}`}>View</Link>
</div>
</div>
</div>
</div>
);
}
}
export default Album;
https://react-pin.netlify.com/
Please follow the above link to what I'm trying to do. Please first go to one "View Data From API"
My github link https://github.com/sultan0/reactpin
The route param is a string. There is no implicit type conversion
with === Operator. Therefore you have to do it explicitly. Pls. see
Comparison operators for a further explanation.
The spread ... Operator is misplaced here.
The solution is:
<ViewPosts posts={posts.find(pv => pv.id === parseInt(match.params.albumId))} />
Update
You would like to use the Switch component from react router:
Switch is unique in that it renders a route exclusively. In contrast, every Route that matches the location renders inclusively.
Pls refer to react router documentation.
I created a pull request as an example. Hope it helps.

ReactJS - Access key of container div on click?

Here is the code that I'm working on right now.
How can I access the key that I have on the container div? Right now I'm just trying to console.log it but ultimately, I need to pass the key to an action so I can make a call to an API.
Thanks for any advice.
I want to access the key on the container div
renderRecipes() {
return _.map(this.props.recipes, recipe => {
return (
<div className="card" style={cardStyle} key={recipe.idMeal}>
<img className="card-img-top" src={recipe.strMealThumb} alt="Recipe" />
<div className="card-body">
<h5 className="card-title">{recipe.strMeal}</h5>
<button className="btn btn-outline-primary" onClick={this.viewRecipe}>
View Recipe Details
</button>
</div>
</div>
)
})
}
render() {
console.log(this.props.recipes);
return (
<div>
<h2>Main Ingredient Search Page</h2>
<SearchField />
<div className="d-flex flex-row flex-wrap">
{this.renderRecipes()}
</div>
</div>
);
}
}
You can do it pretty easily with an anonymous function:
<button className="btn btn-outline-primary" onClick={() => this.viewRecipe(recipe.mealId)}>
View Recipe Details
</button>
But the best way would be to extract the recipe into it's own component. Then it's nicely encapsulated and doesn't re-render onclick references.
class Recipe extends Component {
onViewDetails = () => {
this.props.onItemClick(this.props.id);
}
render() {
const {
name,
thumbnail
} = this.props;
return (
<div className="card" style={cardStyle}>
<img className="card-img-top" src={thumbnail} alt="Recipe" />
<div className="card-body">
<h5 className="card-title">{name}</h5>
<button className="btn btn-outline-primary" onClick={this.onViewDetails}>
View Recipe Details
</button>
</div>
</div>
)
}
}
--
return _.map(this.props.recipes, recipe => (
<Recipe
key={recipe.idMeal}
id={recipe.idMeal}
thumbnail={recipe.strMealThumb}
name={recipe.strMeal}
onItemClick={this.viewRecipe}
/>
);
I think you could do something like this
renderRecipes() {
return this.props.recipes.map(recipe => {
return (
<div className="card" style={cardStyle} key={recipe.idMeal}>
<img className="card-img-top" src={recipe.strMealThumb} alt="Recipe" />
<div className="card-body">
<h5 className="card-title">{recipe.strMeal}</h5>
<button className="btn btn-outline-primary" onClick={() => this.viewRecipe(recipe.idMeal)}>
View Recipe Details
</button>
</div>
</div>
)
})
}
Now, in the onClick function you'll receive the key!
I think you can define your viewRecipe method in this way:
viewRecipe = recipe => e => console.log(recipe)
viewRecipe will be a function that receives a recipe as parameter and returns another function which will be used for the onClick method:
<button className="btn btn-outline-primary" onClick={this.viewRecipe(recipe)}>
Or you can use also the techniques described in the docs which are the following:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

Categories