Render Component By Clicking Text Passed as Props - reactjs

I am new to React and am trying to render a component when a user clicks on some text. The text is a state that's updated in a parent component using a form input and the useState React hook. I can find articles on rendering 'onClick' events, but this isn's a form with type submit or a button, it's just text that's passed down to it as a prop from a state higher up. Also a lot of tutorials seem to be outdated. What I would like to do is be able to click on the text and have it render a new component, with the effect of taking the user to a new 'page' in the browser. The rendered text I want to be able to click on is {user.contacts.username} in the code below. Any help much appreciated as I'm not sure which direction to go in.
import './Contacts.css';
import CreateTimer from './CreateTimer';
function Contacts(user) {
return (
<div className="Contacts">
{user.contacts.username}
</div>
);
}
export default Contacts;

Related

Passed the button text to state, but text reverted back during page refresh in React hooks

I have a record with two buttons, on click on Accept button should send the data back to server and display the text to Save and should not change the text afterwards ( should change only for clicked buttons).
In the below example, it is changing the text during on click, which is fine, but while refreshing the page it set back the text to Accept. Could someone please advise on how can I fix this ?
import { useState, useEffect } from "react";
import "./styles.css";
export default function App() {
const [acceptPlayer, setAcceptPlayer] = useState("Accept");
const postData = (e) => {
const text = "Save";
setAcceptPlayer(text);
};
return (
<div className="App">
<div>
<button onClick={postData} value="accept">
{acceptPlayer}
</button>
</div>
</div>
);
}
https://codesandbox.io/s/admiring-austin-1w1g38?file=/src/App.js
There is nothing wrong with this code. It's the expected behavior of the react. React or any other framework does not persist state on refresh That's the responsibility of the BE.
Solution:
When you can get API to show the data on the page, In the API response, you can return the data in the following format:
{
isAccepted: false,
//...something else
}
When you click on accept button and call the API BE is responsible for updating the isAccepted flag from the next time the API is called. You will get the following response:
{
isAccepted: true,
//...something else
}
Based on isAccepted flag you can toggle the button text.
Of course, it would go back to Accept because react only stores state locally. So every time you refresh the page it will go back to its initial state.
So if you want to get the updated state in your component then you have to fetch the latest data from the database in useEffect and have to set it to a state.

How to create new page without react router

I am creating a react project where I have a button in my home page and when I click it, it should open up a new page that contains a form to fill. Because it is a form and it should only appear after clicking the button on the home page, I don't want to use react router because I don't want the user to just type 'mywebsite.com/form'. I also want the functionality that, when the user submits the form, the page then goes back to the homepage and the data from the form should be available in the home page. For example, if the form had text fields, lists, date pickers, etc. I want all that data in the homepage after the user submits the form.
P.S. I am using material-ui components for my whole app so the text fields, datepickers, etc. are all mui components, so the data fetching from these components has to be according to that.
In your Home component do a conditional render based on if the button was clicked. If it was, render your Form component. Ideally your Home component should be your smart component and the Form should be a dumb component. Meaning that Home should manage all the state and Form is purely just for visuals(UI).
import React, {useState, useEffect} from 'react';
import myForm from './myForm';
const Home = () => {
const [isBtnClicked, setIsBtnClicked] = useState(false);
const [formData, setFormData] = useState(undefined);
useEffect(() => {
if(formData){
setIsBtnClicked(false); // or you can pass this setter to form component and set to false when form is submitted.
}
},[formData])
return (
<>
{isBtnClicked
? <myForm setFormData={setFormData} />
: (<h2>Home With Button</h2>
<Button variant="contained" onClick={() => setIsBtnClicked(true)})
}
};
import React from 'react';
const myForm = ({setFormData}) => {
//assuming you have refs to all inputs
const handleFormSubmit = (e) => {
e.preventDefault();
// construct form data and call setFormData()
}
return (
<>
<form onSubmit={handleFormSubmit()}>
...
</form>
</>
};
Since you are using material-ui, I would recommend you use one of their Dialog components. In case you want to make it look like a completely different page opens up to fill the form, you could use their full-screen dialog component. Build your form within this component and change the props to your liking. Conditionally render the form when the user clicks a button on your home page.
Use the fullscreen prop from the Dialog API and add others that you need.
If i can give my opinion, i think you can use NextJS with server side rendering for this. NextJS provides a structured folder called "pages". You can add your page to this. The redirecting can also be done using router in next package. An easy way without any need for react router. I used to use react router until i found out about this.

React-Typescript pass dynamic value to sibling?

Hi kind of new to coding and React (~3 weeks in) so if I asked this question in a weird way please let me know and I will try to clarify as best as I can.
I am working on these two components and I wanted to pass data that is generated dynamically from COMPONENT1 to COMPONENT2 (see code below).
In COMPONENT1 I am using map to dynamically display an array of buttons. Then using JSX to dynamically add the text in based on the data of an array of objects that was defined. This works fine but what I wanted to do is to take some of the data that was dynamically rendered and pass it on to COMPONENT2 i.e. so each button can send there particular data down to COMPONENT2.
In particular, I want to be able to send obj.text dynamically to COMPONENT2 based on which button I press.
COMPONENT 1
export default function Button(props){
const arrObj = [
{ id: '0', var: 'varString1', text: 'textString1'},
{ id: '1', var: 'varString2', text: 'textString2'}
]
return (
<div>
{arrObj.map( (item) =>
<div key={obj.id}>
<Icon> {`${obj.var}`}<span> {`${obj.text`}</span></Icon>
<Button>{'add something'}</Button>
</div>
}
COMPONENT 2
const Style = (props) => {
return(
<div>
<h1>{`Please ${props.ojb.text}`}</h1>
<Button> {`Please ${props.ojb.text}`} </Button>
</div>
)
Quick example of what I am expecting:
COMPONET1:
<Icon>{refresh}<span> Refresh the page </span>
<Button onClick=(send "Refresh the page to COMPONENT2")></Button>
COMPONET2:
<h1> Please Refresh the Page </h1>
<Button> Please Refresh the Page </Button>
NOTE: I am using Material-UI to style theses components if that helps.
Again please let me know if there is anything that is confusing about this and if there is anything I can do to clarify. Also, in terms of state management I would prefer not to use redux but I am willing to take feedback on any of this.
If The COMPONENT2 is a child component of COMPONENT1:
Save the clicked button value obj.text to the state of COMPONENT1
and pass it to COMPONENT2, you can add a function to change that state
object on the button's onClick event.
If COMPONENT1 and COMPONENT2 are siblings:
Make a function in their parent component to fetch the value from COMPONENT1 using props and pass it to COMPONENT2 from the parent.
Use Context API or a store. (That would be an overkill if your scenario is simple)
And most importantly Welcome to React and Happy coding! :)

How do I dynamically switch between screens and update the url during search input

I have a search input box located in the header. When a user searches and clicks 'enter', an (callback) event is sent out to all of the relevant components that need to react to the search event, including the components that display the search results. My issue is that the header's search box would be visible on other non-search-result screens, and when I search there's no "clean" way of quickly mounting the search-result screens and displaying the search results (I hope it's not too confusing).
So the question is what type of approaches did you take to solve this issue? I was thinking of relying on window location and relying on React-router to load the search-results screen. Then looking at the query parameter (or path that contains the search query) and then kicking off the search.
Update (for clarity):
Go to https://www.brainyninja.com/podcast/78b7ab84cf98735fbadb41bb634320f8 The body component name is
Now type any other search term in the header's search box and click enter
The body component that displays search results is . I need to navigate to the /search route in order to load the component. The only way I figured out how to do that is by doing a 'window.location = "/search/?query=somesearchquery"' command, which reloads the whole page and negates the point of having an SPA. I don't know of any cleaner way of changing the current body component
Any suggestions?
Found my answer here
https://tylermcginnis.com/react-router-programmatically-navigate/
Had to use withRouter since my header was not rendered by a React Router.
Now, what if the Register component wasn’t being rendered by React Router? (Meaning, we’re not passing Register as a component prop to a Route. Instead, we’re just rendering it ourselves like <Register />). If it’s not rendered by React Router, then we won’t have access to history.push. The team thought of this use case so React Router comes with a handy HOC called withRouter. Going back to our Register code above, by adding withRouter, it would look like this
import {
withRouter
} from 'react-router-dom'
class Register extends React.Component {
handleSubmit = (user) => {
saveUser(user).then(() =>
this.props.history.push('/dashboard')
))
}
render() {
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
export default withRouter(Register)

How to handle a checkbox event in react redux?

I ve to redirect to another page when ever the user checks the checkbox.
I am new to react-redux. Right now,all I know is to handle submit
button through dispatchaction but I am wondering how to handle
checkbox action?
export default class myReportForm extends BaseForm {
return(
</form>
</div>
);
}
}
Through handleSubmit in form, I could able to handle submit action. Can any one tell me how to handle checkbox . For example, when I ever click on Afloat , It should redirect me to another page or atleast some action should happen.
mapStateToProps and mapDispatchToActions are helper functions that will wire up the your component to the redux store. mapStateToProps links your component's properties to the state and mapDispatchToActions links its events to actions that can be dispatched.
http://redux.js.org/docs/basics/UsageWithReact.html#container-components
As ever (I'm always recommending this!) have a look at:
https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist (the whole course and its follow-up - Idiomtic Redux - are great).

Resources