I want to know how to send props through Link - reactjs

I made two components and I want to send a props after connecting these components by Link. I'm working on it without using redux, but I found a way to send props and made a code, but the value doesn't come out because I think the method is wrong. I'd appreciate it if you let me know thanks.
SingUp.jsx:
This is the component I'm trying to send a prop. I checked that the value comes out well if I put the value in the input tag. So I think you just need to check the link tag part! I only sent the email value and put email in props to check it
import React, { useState } from 'react'
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import SignUpEmailInput from '../components/SingUp/SignUpEmailInput';
import SignUpLoginButton from '../components/SingUp/SignUpLoginButton';
import SignUpNameInpu from '../components/SingUp/SignUpNameInpu';
import SignUpPassInput from '../components/SingUp/SignUpPassInput';
import SignUpUserInput from '../components/SingUp/SignUpUserInput';
const SignUpWrap = styled.div`
flex-direction: column;
display: flex;
position: relative;
z-index: 0;
margin-bottom: calc(-100vh + 0px);
color: rgb(38,38,38);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 18px;
`
function SignUp() {
const [email, setEmail] = useState("");
const [name, setName] = useState("");
const [userName, setUserName] = useState("");
const [passWord, setPassWord] = useState("");
return (
<SignUpWrap>
<div>
<SignUpEmailInput email={email} setEmail={setEmail}/>
</div>
<div>
<SignUpNameInpu name={name} setName={setName}/>
</div>
<div>
<SignUpUserInput userName={userName} setUserName={setUserName} />
</div>
<div>
<SignUpPassInput passWord={passWord} setPassWord={setPassWord}/>
</div>
<div >
{/* I used Link here */}
<Link to={{pathname:'/birthday', state:{email:email}}} style={{textDecoration : 'none' ,color: 'inherit'}}>
<div>
<SignUpLoginButton email={email} name={name} userName={userName} passWord={passWord}/>
</div>
</Link>
</div>
</SignUpWrap>
)
}
export default SignUp;
Birthday.jsx:
This is the component that I want to receive a prop. I checked that the two components are moved through Link. Can I also know how to get a props value here? I want to check if it went well through console.log
import React, { useState } from 'react'
function Birthday({email, name, userName, passWord}) {
console.log(location.state.email)
return (
<>
Hi
</>
)
}
export default Birthday;

you can use state prop as below - using RR V6 version FYI
<Link to="/hello" state={{ data: 'dummy' }}>
and use useLocation hook to collect data in respective component as
const location = useLocation();
console.log(location.state);
A sample e.g. below
https://stackblitz.com/edit/react-ts-mxqsgj?embed=1&file=App.tsx

<Link to="/birthday" state={{email : email }} style={{textDecoration : 'none' ,color: 'inherit'}}>
you can get by using useLocation
import React, { useState } from 'react';
import { useLocation } from 'react-router-dom'
function Birthday() {
const location = useLocation()
const { email } = location.state
console.log(email)
return email
}
export default Birthday;

Related

How to style a component based on state in Styled Components?

I am trying to change the input background based on the useState hook in Styled Components in React.
Here is my code:
const [searchActive, setSearchActive] = useState(true);
<div className="search" searchActive={searchActive}>
<input id="input"/>
</div>
Here is my Styled Component code:
.search {
background: ${(searchActive) => (searchActive ? "red" : "yellow")};
}
any advise would be very appreciated.
Creating a component and passing in props will work:
import React from 'react'
import styled from 'styled-components'
const Search = styled.div`
background: ${props => (props.searchActive ? 'red' : `yellow`)};
`
const Parent = () => {
return (
<Search searchActive={searchActive}>
<input id="input" />
</Search>
)
}
export default Parent
Only different is whatever you have style wise for search can be added to the Search component but you do not show any further code so I do not know how you're bringing it in.
You can also externalize the components with something like:
import styled from 'styled-components'
export const Search = styled.div`
background: ${props => (props.searchActive ? 'red' : `yellow`)};
`
then bring it in:
import {Search} from './search.js'
Add 'props' in styled-component like this;
.search {
background: ${props => props.searchActive? "red" : "yellow"};
}
You can declare and directly use Styled Components in jsx . They are not required to be used as a className. Maybe this approach is useful for you.
import React, { useState } from "react";
import styled from "styled-components";
export default function App() {
const [searchActive, setSearchActive] = useState(true);
const [value, setValue] = useState("");
const Search = styled.input`
background: ${(props) => (props.searchActive ? "red" : "yellow")};
`;
return (
<Search
searchActive={searchActive}
value={value}
onChange={(e) => {
setValue(e.target.value);
setSearchActive(false);
}}
/>
);
}

.map() in reactJs is not returning anything

i'm new to react and im trying to add render a list of items from an external SidebarData.js file (in the same root /components/..)
i'm not sure why my map function is not returning anything.
i get a list of elements thats correct, but the item.title and item.path seem not to render...
I feel there's a problem with the props.
I tried to write just
render(){
<h1>{SubmenuData[1].title}</h1>
}
and it works fine, but when i try to map on the full array, it doesn't seem to render anything. it renders the correct number of elements, but the title and path are not returning...
Here's my two components : Sidebar (Main one)
import React from 'react'
import styled from 'styled-components'
import { SidebarData } from './SidebarData'
import Submenu from './Submenu'
const Nav = styled.div`
background: #f5f5f5;
color: #7d7d7d;
display:flex;
justify-content:flex-start;
height:100%;
width:15%;
`
const Sidebar = () => {
return (
<>
<Nav>
{SidebarData.map((item, index)=>{
return <Submenu item={item} key={item.index} />
})}
</Nav>
</>
)
}
export default Sidebar (Where i think there's a problem)
and Submenu
import React, { Component } from 'react'
import styled from 'styled-components'
import { Link } from "react-router-dom"
const SidebarLink = styled(Link)`
display: flex;
color: #404040;
`
const SidebarLabel = styled.span`
color:#000;
`
const Submenu = (item)=>{
return (
<SidebarLink to={item.path} >
<SidebarLabel>{item.title}</SidebarLabel>
</SidebarLink>
)
}
export default Submenu
Your style of receiving props is mistake i guess. Destructure the props like:
const Submenu = ({item})=>{
return (
<SidebarLink to={item.path} >
<SidebarLabel>{item.title}</SidebarLabel>
</SidebarLink>
)
}
export default Submenu

ReferenceError: Helmet is not defined in Fusion.js

I was building a Todo app referring to Fusion.js docs
I added fusion-plugin-react-helmet-async plugin using yarn but it seem to have an error.
I tried to import Helmet but that does not seem to work. Is there something that I'm missing. Could anyone please help?
Code
import React, { useState } from "react";
const Root = () => {
const [todos, setTodos] = useState([]);
const [inputText, setInputText] = useState("");
...
return (
<React.Fragment>
<Helmet>
<style>
{`
body {
background-color: #f5f5f5;
font: 24px 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
`}
</style>
</Helmet>
<h1>todos</h1>
<div className="container">
...
</div>
</React.Fragment>
);
};
export default <Root />;
Error Message
import statement was missing in the docs. I opened a GitHub issue on this and someone from the Fusion.js team corrected the docs.
After adding the below statement, it worked.
import { Helmet } from "fusion-plugin-react-helmet-async";

Passing custom props to each styled component through Provider

I would like to pass a custom prop (exactly: theme name as string) to each passed styled component through Provider, so it was available throughout the css definition.
ThemeProvider almost does it, but it expects object, not the string. I do not want to pass whole object with theme settings, just the name of my theme.
I do not want to use special theme prop or similar, because then I would have to it manually every single time I create new styled component. Provider seems like the best option if only it cooperated with string.
Is there any possibility to pass a string through Provider to Consumer builded in styled components?
EDIT:
[PARTIAL SOLUTION]
I found what I was looking for when I realized styled-components exports their inner context. That was it. Having access to pure react context gives you original Provider, without any 'only objects' restriction ('only objects' is a styled-components custom provider restriction).
Now I can push to each styled component exactly what I want and if I want.
import styled, { ThemeContext } from 'styled-components';
const StyledComponent = styled.div`
color: ${props => props.theme == 'dark' ? 'white' : 'black'};
`;
const Component = props => {
const theme = 'dark';
return (
<ThemeContext.Provider value={theme}>
<NextLevelComponent>
<StyledComponent />
</NextLevelComponent>
</ThemeContext.Provider>
);
};
Hope I have this correct, from what I've been able to glean. I haven't tried this out but it seems it might work for you. This is lifted directly from the reactjs.org docs regarding context. It passed the string name of the theme down.
const ThemeContext = React.createContext('green');
class App extends React.Component {
render() {
return (
<ThemeContext.Provider value="blue">
<SomeComponent />
</ThemeContext.Provider>
);
}
}
function SomeComponent(props) {
return (
<div>
<OtherComponent />
</div>
);
}
class OtherComponent extends React.Component {
static contextType = ThemeContext;
render() {
return <ThirdComponent theme={this.context} />
}
}
I hope this helps you understand the idea behind ThemeContext from styled-components. I've passed string "blue" to ThemeContext just to show, that it should not be object and you can use just string.
import React, { useContext } from "react";
import ReactDOM from "react-dom";
import styled, { ThemeContext } from "styled-components";
// Define styled button
const Button = styled.button`
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
color: ${props => props.theme};
border: 2px solid ${props => props.theme};
`;
// Define the name of the theme / color (string)
const themeName = "blue";
const ThemedButton = () => {
// Get the name from context
const themeName = useContext(ThemeContext);
return <Button theme={themeName}>Themed color: {themeName}</Button>;
};
function App() {
return (
<div className="App">
<ThemeContext.Provider value={themeName}>
<ThemedButton />
</ThemeContext.Provider>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Demo: https://codesandbox.io/s/styled-components-example-with-themecontext-cso55

Styled-components: Override component style inside a new component

I am trying to override the style of a component inside another component.
So, I have a component A, with some div's inside(Wrapper, Header).
In a new component, I am trying to override component A. Inside that override I want some new styling to the Header component. I know I can reference a component inside the same component but I can't find any info about referencing inside a new component.
// Component A
import React from "react";
export default ({
className,
title
}) => (
<Wrapper className={className}>
<Header>{title}</Header>
</Wrapper>
)
);
const Header = styled.h2`
padding-left: 0;
`;
// Component B
import React from "react";
export default () => (
<CustomA>
/* content */
</CustomA>
)
);
const CustomA = styled(<A />)`
${Header} {
padding-left: 20px;
}
`;
I expect Header to be changed but I get "Header is not defined".
There are a couple of issues to address.
You can follow along on CodeSandbox.
1. Export Header component from Component A
You need to make Header component available outside Component A so that it can be referenced within Component B.
import React from "react";
import styled from "styled-components";
export const Header = styled.h2`
padding-left: 0;
`;
export default ({ className = "", title }) => (
<div className={className}>
<Header>{title}</Header>
</div>
);
2. Errors in Component B
There are three issues here.
You need to pass the component name, not the instance to styled() function.
Instead of const CustomA = styled(<A />) where <A /> is an instance,
Do const CustomA = styled(A).
You need to import Header component exported from Component A.
Now you can reference is within styled(A) as ${Header}.
import styled from "styled-components";
import A, { Header } from "./CustomA";
const CustomA = styled(A)`
${Header} {
padding-left: 20px;
}
`;
export default () => <CustomA title="Component B Content" />;
The last issue is that, you aren't passing the title (I also did className = "" in Component A to make it optional).
First of all you need to use styled like below:
const CustomA = styled(A)``;
instead of
const CustomA = styled(<A/>)``;
Secondly, try the following code:
const CustomA = styled(A)`
h2{
padding-left: 20px;
}
`;
try
const CustomA = styled(A)`
padding-left: 20px;
`;

Resources