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);
}
}
Related
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>
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.
How do you get access to the calling component in react?
function MyCallingComponent() {
return <MyReadingComponent/>
}
function MyReadingComponent() {
console.log(callingComponent.state)
}
You don't. The parent component can pass data and functions to the child via props, though. So for instance, if the parent needed a callback from the child in some circumstance:
function MyCallingComponent() {
function callback() {
// ...
}
return <MyReadingComponent callback={callback}/>;
}
function MyReadingComponent({callback}) {
// ...use `callback` where appropriate...
}
react uses unidirectional data flow, so if you need to access parent's state in your child component you need to pass it down as a prop.
class ParentComponent ...{
state={ foo : 'A' }
render(){
return <ChildComponent foo={this.state.foo}/>
}
}
as #t-j-crowder has said if you need to pass data from child to parent you may use callback method.
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.
I have a React component which i need to update when i call onSubmit on a child component
The parent component which needs to get updated looks like this:
componentDidMount() {
axios.get('/todo')
.then(function (response) {
this.setState({
todoList: response.data
})
}.bind(this))
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<div>
<Form/>
{this.state.todoList.map(todo => {
return (
<TodoItem
id={todo._id}
key={todo._id}
itemToDo={todo.todoItem}
/>
);
})}
</div>
)
}
When i submit the <Form/> component i call
handleSubmit(e) {
e.preventDefault();
axios.post('/todo', {
todoItem: this.state.todoItem
})
}
where i need to update the parent component, in order to get the updated list from the server
I am not sure entirely about your question but you can pass a function (updateParent) from parent component to the child component as a property and when you want to update the parent component, invoke this.props.propFromParentComponent in your child component. If you want the parent component to update, use the this.setState({..}) and update the state of the component to update the parent component inside of this function (updateParent).
If you have a store that the parent component is listening to for prop changes you could have the child component update the store which would in turn update the parent. This would be assuming you have a unidirectional flow of data.
If you need to have the child component directly update it's parent the answer AliF50 supplied would work.