get id value of url in another component passed via props - vue - javascript

I am creating one reusable component. There are two child components. This flow is like below
Child component 1 -> Parent Component -> Super Parent main Component
In child component, i am creating a prop url then pass into Parent component then pass to Super Parent component where i am passing value like this below.
Child Component
prop: {
urls: {
type: Object,
required: true,
default: () => ({
saveProduct: '/entity/save',
updateProduct: '/entity/update
})
}
}
Parent Component
<ChildComponent :urls = "uris" />
props: {
uris: {
type:Object,
required:true,
default: () => ({})
}
}
Super Parent Component
<ParentComponent :uris="urls" />
data() {
return {
urls: {
saveUri: `/products/${this.$route.params.id}/categories`,
updateUri: `/products/${this.$route.params.id}/categories/${this.productId}`
}
}
}
Here i am giving snippets for flow not full code. I want to know the generic way to get the productId value in Super parent.
In here, i can get this (this.$route.params.id) value but how can i get productid value available in super parent from Child component.
Any generic example will be helpful for me... How to send data from one component to next of next component?

Props are for passing data downwards from parent to child. To send data upwards from child to parent, emit and event from child and listen to it in parent.
this.$emit('clicked', 'someValue')
Another option would be using a global state store like Vuex.

Related

(Vue.js 3 Options API) How do I access a child method?

I need to access a child component's method using Vue.js 3 with Options API. There is an answer at How to access to a child method from the parent in vue.js, but it is for Vue.js 2 and Vue.js 3 but with Composition API.
I still tried this, all in the parent component:
<dropdown-list #update="updateChildComponents"></dropdown-list>
<child-component-1 ref="childComponent1Ref" :url="url"></child-component-1>
<child-component-2 ref="childComponent2Ref" :url="url"></child-component-2>
and
methods: {
updateChildComponents() {
this.$refs.childComponent1Ref.childComponentMethod();
this.$refs.childComponent2Ref.childComponentMethod();
}
}
This actually successfully accesses the method, but I think this may not be the right way.
Secondly, I use a prop in the child component that I update in the parent and use in the child component's method, which updates only after the second event. I think these two may be related.
Child component:
props: ['url'],
methods: {
childComponentMethod() {
console.log(this.url); // can access the value from the previous event
}
}
I appreciate any help.
For communication between the parent and the children you should trasfer the value with props. In case the value is changing in the parent you must add watch.
It called 1 way binding because the parent cant see the changes in the child component.
Parent -> child = use props.
Child -> parent = use emits and on event.
<script>
import { reactive,watch, computed,onMounted } from "vue";
export default {
components: {
},
props: { metadata: String },
emits: [""],
setup(props) {
onMounted(async () => {
//first initilize
if (props.metadata) {
state.metadataName = props.metadata;
}
});
//track after the changes in the parent
watch(
() => props.metadata,
async (metadata) => {
if (metadata) {
}
}
);
return {
};
},
};
</script>

Performance: Dispatching an action vs passing as props in React

I have a technical question. I am trying to pass a value from child component to store by using action dispatcher inside my child component. This action dispatcher then updates the state value in the reducer.
Is it advisable to pass value from the child component this way? will it affect the performance of the react app?
Or should I use props to pass from child to parent component and then update the state.
Please advise as I searched a lot about this but didn't get any info.
Problem with passing dispatcher to your child is your child component is not very reusable. I would suggest to pass a callback method to your child which contains the logic of dispatching the event.
Parent:
class ParentComponent extends React.Component {
loginHandler(){
...
this.props.someMethod();
}
render() {
return {
...
<ChildComponent click="loginHandler"></ChildComponent>
...
}
}
}
const mapDispatchToProps = dispatch => {
return {
// dispatching plain actions
...
someMethod: () => dispatch({ ... }),
...
}
}
export default connect(null, mapDispatchToProps)(ParentComponent);
Child Component:
function ChildComponent({click}) {
return {
...
<button click={click}></button>
...
}
}
Now with this approach your child approach doesn't carry any business logic. It can be used at multiple places.

React child component not updating parents state, so second child is not noticing the changes

Curently I have this structure.
Child1 <---- Parent ----> Child2
Parent component has this state
this.state = {
authenticationChecked: true,
isAuthenticated: true,
sideBarRetracted: false
}
this.retract = this.retract.bind(this);
this.unretract = this.unretract.bind(this);
and the following functions
retract() {
this.setState({
sideBarRetracted: true
}, () => {
console.log("retracted")
console.log(this.state.sideBarRetracted) //I can see this changing to true, but the child wont take it into effect, even tho if i hardcode it , it will
});
}
unretract() {
this.setState({
sideBarRetracted: false
})
console.log("unretracted")
}
Which is pased to both childs
<SideBar retract={this.retract} unretract={this.unretract} retracted={this.state.sideBarRetracted} {...this.props}/>
<PrivateRoute authed={this.state.isAuthenticated} path="/skadi" render={(props) => <Skadi retracted={this.state.sideBarRetracted} {...props}/>} />
Now my question is. I supposedly should receive that as a prop in a child component, for example lets say in the sidebar component which is a child. Whose constructor is this, and im supposed to receive the prop there and assign it to the state
constructor(props) {
super(props);
this.state = {
retracted: this.props.retracted
}
}
It works properly so far, but now I have the following issue. This same component has a function onClick() which will change that specific state
<FontAwesomeIcon className="registerIcon" icon={faArrowAltCircleLeft} onClick={this.props.retract} />
<FontAwesomeIcon className="expandicon-retracted" icon={faArrowAltCircleRight} onClick={this.props.unretract} />
But point is, this is not working, the state is not being updated in the parent component. I can change it manually (hardcoding) and I see the child component reacting to the change, but i cant make it react with the onclick() update
At the same time, I have my Child2 component, who has been passed the parent state as well. Will its state update if I update the parent component using CHILD1 ?
I have seen that i should use something like this in the child2 , but well it wont work so far (mainly because parent component isnt updated afaik)
constructor(props) {
super(props)
this.state = {
sideretracted: false
}
console.log("props in skadi")
}
componentWillReceiveProps(nextProps) {
this.setState({ sideretracted: nextProps.sideBarRetracted});
}
You shouldn't set the child state from the props received from the parent component.
Since you are updating the state of child component from the methods bound to the child components it isn't reflected in the parent component.
One thing you could do is pass a method from the parent to update the state of the parent component and the child state gets updated by itself since it will be passed the new state variable from parent as a prop.
You could have the toggleRetract method defined in the parent to set the parent state and pass it as a prop to the child component which would trigger it and set the parent state for you which will be passed down to the children components as props (like how you are passing the state props).
For example
function Toggle() {
const [on, setOn] = React.useState(false)
const toggle = () => setOn(o => !o)
return <Switch on={on} onToggle={toggle} />
}
function Switch({on, onToggle}) {
return (
<div>
<div>The button is {on ? 'on' : 'off'}</div>
<button onClick={onToggle}>Toggle</button>
</div>
)
}
Here Toggle is the parent component and Switch is the child component and the parent component passes the on state as well as onToggle method which the child component uses to display and update the state respectively.
More info here

ReactJS ComponentWillMount() after passing Props

I want to ask why the child ( ComponentWillMount() ) component is only once rendered, once I am passing props to it everytime on onClick.
Once I click some button that is passing props to the child, the ComponentWillMount() of child is not triggering again, only in the first click only.
Parent Component:
render(){
return(
<div>
<AppModuleForm
editID = {this.state.editID}
editURL = {this.state.editURL}
editConf = {this.state.editConf}
editDesc = {this.state.editDesc}
editIcon = {this.state.editIcon}
editParent = {this.state.editParent}
editOrder= {this.state.editOrder}
status={this.state.status}
moduleList={this.state.moduleList}
updateAppModuleTree={this.updateAppModuleTree.bind(this)}/>
</div>
)
}
Child Component:
constructor(props){
super(props)
console.log(this.props.editDesc)
this.state={
url:'',
description:'',
parentID:'',
order:'',
configuration:'',
icon:'',
parentIDList:[],
urlDuplicate: false,
isSuccess: false,
errorMessage: '',
}
}
componentWillMount(){
if(this.props.status==='edit'){
let {
editURL,
editDesc,
editParent,
editConf,
editIcon,
editOrder} = this.props
this.setState({
url:editURL,
description:editDesc,
parentID:editParent,
order:editOrder,
configuration:editConf,
icon:editIcon,
})
}
}
componentWillReceiveProps(nextProps){
if(nextProps.status != this.props.status){
if(this.props.status==='edit'){
let {
editURL,
editDesc,
editParent,
editConf,
editIcon,
editOrder} = this.props
this.setState({
url:editURL,
description:editDesc,
parentID:editParent,
order:editOrder,
configuration:editConf,
icon:editIcon,
})
}
}
}
ComponentWillMount is mounting lifecycle method which will be called before mounting your component hence initialisation can be done in that while ComponentWillReceiveProps will be called once props are changed and you will get changes in nextProps parameter.
First you need to read https://reactjs.org/docs/state-and-lifecycle.html
and understand where to use props and why you need to pass something into component state.
From http://lucybain.com/blog/2016/react-state-vs-pros/
So when would you use state?
When a component needs to keep track of information between renderings
the component itself can create, update, and use state.
So you shouldn't transfer to state anything that will not change internally during component live cycle. As I can see all props those you pass to component are most likely will not be changed from within the component, all callbacks and icons you should take from props in component jsx.
If you have some editable data that you pass into its props from parent, on component mount (use componentWillMount()) you can copy that data to component state.That means all data will be stored in component internally and will not being overwritten on every render() call from passed props.
If you need to check if new props contains changes you can use componentWillReceiveProps(newProps) and there you can compare newProps with this.props and and process changes if needed.
Also i can suggest you to rename component callbacks handlers with respect to naming best practices:
<div>
<AppModuleForm
handleEditID = {this.onEditID}
handleEditURL = {this.onEditURL}
handleEditConf = {this.onEditConf}
handleEditDesc = {this.onEditDesc}
handleEditIcon = {this.onEditIcon}
handleEditParent = {this.onEditParent}
handleEditOrder= {this.onEditOrder}
status={this.state.status}
moduleList={this.state.moduleList}
updateAppModuleTree={this.updateAppModuleTree.bind(this)}/>
</div>
And I dont see any reasonable purpose to declare or to store functions in components state. So you can consider to move your handlers this.state.editID
etc. to parent component this scope. Like that
onEditId = () => { /* function code */ }
If you use arrow function = () => it automatically binds to component this and you don't need to bind them manually like you do in
{this.updateAppModuleTree.bind(this)}
After all that may be you will understand more clearly how you should manage your components life cycle and your problem will no longer be relevant.

Vue.js - How to render data changes in child component?

So I have a parent component Store that has a child component called Order. The data from the parent is passed via props to its child, like so:
parent
<Order :order="order" />
child
props: ['order']
I need to use a new data variable in the child component called orderIds, so I declare that:
child
props: ['order'],
data: () {
return {
orderIds: Object.keys(this.order)
}
}
Then, I render the orderIds in the view:
{{orderIds}}
Now, whenever the order data changes in the parent, it updates the prop order in the child, but it is not propagated through to orderIds.
How would I update orderIds when something changes in order?
Instead of data use a computed property.
computed: {
orderIds: function () {
return Object.keys(this.order);
}
}

Categories

Resources