Im using React Router to navigate to a page in my app like this:
<Link to={`/single/${this.props.data.pageId}`} params={{singleId: 1}}>GotoPage!</Link>
This works fine but I would also like to pass an additional property to the new page.
When rendering a component without using Link I would do something like:
<MyComponent myProp={this.props.data}/>
I have tried passing myProp={this.props.data} along in params like this:
<Link to={`/single/${this.props.data.pageId}`} params={{singleId: 1, myProp={this.props.data}}}>GotoPage!</Link>
But it does not seem to work as myProp is undefined on the new page as oppose to pageId which I can get like:
this.props.params.pageId;
Am I not supposed to be able to pass non-route related parameters with Link?
In the documentation for Link and also the source, there's no mention of it taking param. But I get what you're trying to do.
Instead of hard-coding routes, may I recommend using react-router's history function router.push(). Do something like this instead:
class Foo extends React.Component {
...
const handleNewRoute = () => {
let { pageId } = this.props.data
let singleId = '1'
this.context.router.push({ // use push
pathname: `/single/${pageId}`,
query: { singleId }
})
}
render() {
return (
<button onLeftClick={this.handleNewRoute} />
)
}
}
By the way, in React/JSX, something like ...{{singleId: 1, myProp={this.props.data}}}... should be <Link...foobar={{singleId: 1, myProp: this.props.data}}>. The former syntax is wrong.
I think the better way to get the additional data is an ajax.
But if you want your way to do this,I check the api of Link and I find a query property.
query:
An object of key:value pairs to be stringified.
so you can use this to pass a object of key:value to the next route,but this object will be stringified and passed though the url I think.I prefer an ajax for this.
Related
Within Session() I want to access stateABC, which is in Item5().
The setup of my code looks like this:
Session.js:
function Session() {
//get handleRender(item).props.stateABC here
return (
<View>
{handleRender(item)}
</View>
);
}
handleRender.js:
export function handleRender(item) {
if(item == "Item5"){
return (
{Item5()}
);
}
}
Item5.js:
export function Item5() {
const [stateABC, setStateABC] = useState("123");
return (
....
);
}
I tried to get the value in Session() by using handleRender(item).props.stateABC, but all I get is an empty value.
Is it possible to receive properties from a function like that or are props only accessible in class components?
Any help is appreciated.
Thanks
If you need to access to stateABC value from Session component you have to pass a callback prop down from Session to Item5 and call it every time you update stateABC with setStateABC, passing the new value to the callback.
This is the simplest approach, you could also use React Context API or even something like Redux if you think that your app will grow in complexity.
Also, the approach that you tried to use is a bad idea. It works only in class component but in any case you should not use it, it's a bad thing to access props directly.
How can I always get the same part of the URL in react?
example:
http://localhost:3000/supplier/924511e8-9056-4c1e-9976-625bf042924e
I only want "supplier", but this can be anything else. So it's possible for it to be:
http://localhost:3000/product/924511e8-9056-4c1e-9976-625bf042924e
Then I want "product"
But it can also be just http://localhost:3000/supplier/ also in this case I only want the supplier. And this can be anything.
How do I do this? If I've already tried it with pathname.slice(0, pathname.indexOf("/") but this doesn't seem to work.
So I only want the string after the http://localhost:3000/want this/ no matter if there is anything after it or not.
You can use the split method as below:
const url = 'http://localhost:3000/supplier/'
const want_this = url.split('/')[3]
Just use useParams from react router dom
import {useParams} from "react-router-dom";
function Child() {
// We can use the `useParams` hook here to access
// the dynamic pieces of the URL.
let { id } = useParams();
return (
<div>
<h3>ID: {id}</h3>
</div>
);
}
I don't want to have a handle refresh function in every single screen in my project, so I created a Helper.js to handle this. This function has this.setState and another call for a function inside the screen component. This is what I got so far but it returns an error.
Exported function
export function handleRefresh(component) {
const {page, refreshing} = component.state
component.setState(
{
page:1,
refreshing:true
},
() => {
component.makeRemoteRequest();
}
);
};
and I call it in the component like this:
<FlatList
...
onRefresh={()=> handleRefresh(this)}
refreshing={this.state.refreshing}
...
/>
I saw that you can pass "this" as a param, but the error still says it is undefined.
setState shall be within that screen always where you are using FlatList because after making API you have to update and control the state of that screen.
All the states will be in the component where FlatList using.
Use case are not logical in my view. You can try to create a helper function which accepts different functions params like: page, isRefreshing and return the API response and also the API url and datapost will also be dynamic. Because you want to use it in many areas. It will be difficult to maintain.
So, If you like then use redux what you want.
https://snack.expo.io/#prashen/flatlist-onrefresh
You can do in this way.
class AComponent {
...
render() {
const thisComponent = this;
<FlatList
...
onRefresh={()=> handleRefresh(thisComponent)}
refreshing={this.state.refreshing}
...
/>
}
};
All this. uses refer a same class or function. Only use IF i'ts a child function, component or method.
I'ts don't work out of class function original, you can make a bridge for share data or status.
You can use redux for it and using stores for update screen state.
I want to make a page with url users/:userId where userId will be (java, cpp, c).So in home page if click on java button it will open a page wit url users/java, similarly for c and cpp.All these pages will have same layout with different data.For this I made a simple component as Lang.jsx
export class Lang extends Component{
render() {
const { data } = this.props;
return (
<div>
<h1>{data.lang}</h1>
</div>);
}
}
In Router class we have to write something as
<Route path="users/:userId" component={Lang} />
But it is not clear how to pass userId in router and
load Lang for each url?
Use Link for these java, cpp, c, like this:
<Link to='users/java'>Java</Link>
<Link to='users/cpp'>Cpp</Link>
<Link to='users/c'>C</Link>
If you are using history.push() then write it like this:
hashHistory.push('users/java');
Note: You can make that userid optional because if you don't pass userid it will not match to any route, write it like this to make it optional:
<Route path="users/(:userId)" component={Lang} />
Now if you don't pass anything then also it will open the Lang page.
One more thing since you are passing the parameter by name userId, so it will available by this.props.params.userId not by this.props.data.lang.
I'm not completely sure what you're trying to do here, but if you have a look at this.props inside of lang, there will be a params key (this.props.params), which will be an object containing the userId.
eg:
this.props = {
params: {
userId: '1234',
},
}
This means that when you go to /user/1234, the userId key will have the value of 1234.
I'm not really sure what you're expecting the value of data.lang to be. Are you wrapping the routes in another route that provides that prop? What library are you using for lang?
How do I get the params of a route inside a react component
Im using react containers from the react composer package
if this is the whole route
https://learnbuildrepeat-tevinthuku.c9users.io/ReadProjectMeta/wD98XTTtpf8ceyRJT
How do I get only
wD98XTTtpf8ceyRJT
and store its value in a variable inside a react component.
Ive tried to use
FlowRouter.getParam() but it doesnt work. I keep getting undefined
import React from 'react';
export default class ReadProjectMetaLayout extends React.Component {
render() {
var category = FlowRouter.getQueryParam();
console.log(category);
return (
<div>
<h4>Hello World</h4>
</div>
)
}
}
this is the route
FlowRouter.route("/ReadProjectMeta/:_id", {
name: 'project.meta',
action(params) {
mount(ReadProjectMetaLayoutContainer, {
components: (<ReadProjectMeta _id={params._id}/>)
})
}
});
What could be the problem and how do I solve it
To only get the last part of the string:
location.pathname.substr((location.pathname.lastIndexOf('/')+1))
Another pure meteor based thing you can try is from this reference:
FlowRouter.getParam(":_id");
NOTE: Your solution didn't work as you are getting query parameter, query parameters are the parameters that are passed in the url after '?'
i.e. /apps/this-is-my-app?show=yes&color=red
Here in above code color and show are query parameters, while apps is a part of pathname
FlowRouter.getParam(paramName) returns the value of a single URL
parameter
FlowRouter.getQueryParam(paramName) returns the value of a single URL query parameter
Reference:
https://guide.meteor.com/routing.html#accessing-route-info