When the lifecycle function(lets say afterUpdate()) in a Svelte component gets invoked. Does it cause the component to rerender?
For example
<script>
import { afterUpdate } from 'svelte';
afterUpdate(() => {
console.log('the component just updated');
});
</script>
Is this simply just a component updating or does rerendering occur?
The afterUpdate function executes a callback after the component get updated: https://svelte.dev/docs#run-time-svelte-afterupdate
Is this simply just a component updating or does rerendering occur?
It simply lets you do something after an update occurred. Of course, you can update properties and it will rerender the component, but Svelte will manage everything for you so you have to worry about an infinite update loop:
For example, here the method afterUpdate will be called only twice:
on mount
when name change due to the setTimeout
<script>
import {afterUpdate} from 'svelte';
let name = 'world';
let counter = 0;
afterUpdate(() => name = `${name} ${counter++}`)
setTimeout(() => name= 'everybody', 1000)
</script>
<h1>Hello {name}!</h1>
Related
I am working on nuxt 3 and I need re render component after API response.
<template>
<AssetsTab
:form-data="formData.assets"
:loader="loader"
#on-submit="submitForm"
/>
</template>
<script setup>
onMounted( async () => {
await getDetails(); //API call
});
</script>
Here once the API call getDetails() successed. I need to rerender AssetsTab component again.
Use a reactive variable like const isApiRespond = ref(false) and make the variable true in the getDetails function when you get the successful API response. Then in the template use v-if like below,
<AssetsTab
v-if=isApiRespond
:form-data="formData.assets"
:loader="loader"
#on-submit="submitForm"
/>
Now if you again want to Re-Render your component then use a key prop in your component. Whenever your props value update, the component will auto-update.
<AssetsTab
v-if=isApiRespond
:key="rerendervalue"
:form-data="formData.assets"
:loader="loader"
#on-submit="submitForm"
/>
In above code whenever your key value update the whole component will auto update.
Here is a VuePlaygroud Link check it's console you will understand.
I have a small question regarding passing functions between components that are not in parent/child relationship.
My structure inside App.
function App() {
return (
<div className="App">
<Header/>
<Pfl />
<Sdc/>
<Checkscan/>
</div>
);
}
Those 3 components have an on click function attached to a button i want the button from the pfl component to trigger all 3 on click functions.
When i click on the button in the pfl component i want to trigger the function running in the pfl component and the functions that are inside the Sdc,Checkscan component.
Whats the best way to do it and pass the functions from the other components so when i click the button inside the pfl component it will trigger all the methods from the other 2 components(Sdc,Checkscan)?
Or if I make a container that looks like this
export default function Apicontainer() {
return (
<React.Fragment>
<Pfl />
<Sdc />
<Checkscan />
<Button variant="contained">Start</Button>
</React.Fragment>
)
}
and in app.js i only have the Apicontainer.
How do i transfer all the functions to work in that button click Component
I just wrote some quick and dirty example code to show how you can share things between components via a parent component:
export default function Apicontainer() {
const [sharedState, setSharedState] = useState({sdc: null, checkScan: null})
function pflFunction() {
console.log('pflFunction')
// do your stuff here. I would update state with some reasonable data, and then pass
// the relevant data to the component that needs it. This is just an example.
setSharedState({sdc: 'sdcData', checkScan: 'checkScanData'})
}
return (
<React.Fragment>
<Pfl onClick={pflFunction} />
<Sdc data={sharedState.sdc}/>
<Checkscan data={sharedState.checkScan} />
<Button variant="contained">Start</Button>
</React.Fragment>
)
}
// Example of how to trigger a function inside a component (separate file):
export default function Sdc({data}){
const sdcFunction = useCallback(() => {
// implement the function you want to call here. useCallback makes sure to keep
// a stable reference to the function, so that you can rely on it in a useEffect
}, [])
useEffect(() => {
if(data){
// do something. This effect will run whenever the data or sdcFunction changes.
sdcFunction()
}
}, [data, sdcFunction])
return (
<div>your Sdc view code here</div>
)
}
For the record: If fplFunction is anything else than an onClick handler, you should make sure the function has a stable reference, using useCallback (as in the last component)
I have multiple views in my web application. On each view, I need to check for a "change event". As soon as a value is changed (without submit), I want to set a boolean in my bean true. Is this possible? There are many inputs so a on every component would be annoying.
I'm working on a Wildyfly server and use Primefaces 6.2, JSF 2.2.
Thx and greetings!
I think that can be achieved with jquery + remote command, for example:
<script type="text/javascript">
$(document).ready(function () {
$(".ui-input").on('change', function (event) {
setBooleanValue()
});
});
</script>
and then the remoteCommand which will trigger a method on managed bean responsible for setting the boolean value:
<h:form>
<p:remoteCommand name="setBooleanValue" action="#{myBeann.callMethodToSetBoolean}"/>
</h:form>
The remoteCommand will be called on every (primefaces) input change.
Also if you have ajax updates on the page you'll need to re-register the jquery change event on inputs after the ajax call:
<script type="text/javascript">
$(document).ready(function () {
$(".ui-input").on('change', function (event) {
setBooleanValue()
});
});
$(document).on("pfAjaxComplete", function () {
$(".ui-input").on('change', function (event) {
setBooleanValue()
});
});
</script>
I have a React component that is passing an object to a child element containing an input field to be modified via a passed function. The input field is changing the state of the child element but somehow, without invoking the passed function, the props object is being modified.
this is the render function of the parent class:
render: function() {
const newTriggerClass = this.state.item.triggerID === ""
? " new-trigger"
: "";
return (
<div className={newTriggerClass}>
<div className="triggers-detail">
<section className="trigger-info group">
<TriggerInfoEntry
item={this.state.item}
triggerState={this.state.editTriggerState}
columnHeaders={this.props.columnHeaders}
hideDetail={this.hideDetail}
editAction={this.props.editAction}
editToggle={this.editToggle}
_onChange={this._onInfoChange}
createAction={this.props.createAction}
deleteAction={this.props.deleteAction}/>
</section>
<section className="trigger-actions group">
<TriggerActionEntry
item={this.state.item}
actionState={this.state.editActionState}
editToggle={this.editToggle}
editAction={this.editTriggerAction}
actionIndex={this.state.selectedActionIndex}/>
</section>
</div>
<div className={"modal-overlay" + newTriggerClass}>
</div>
</div>
);
},
and the child TriggerActionEntry is setting it's own state.item to a clone of props.item.
propTypes: {
item: React.PropTypes.object.isRequired,
editAction: React.PropTypes.func.isRequired,
editToggle: React.PropTypes.func.isRequired,
actionState: React.PropTypes.bool
},
getInitialState: function() {
return {
item: assign({testy: true}, this.props.item),
actionIndex: 0,
deleteState: false,
editState: false
};
},
when I change the state of the child component (state.item) through an input, the parent state gets changed! I am not sure of the cause. Nothing that I have read online alludes to this behavior. Any help is appreciated.
UPDATE:
#garrettmaring The code I use to change state is only designed to work on the child state which is set in the getInitialState as a clone of this.props.item through assign which is my alias for object-assign which is an Object.assign ponyfill. The form to change item is actually one more child down. Here is the render of TriggerActionEntry
<div>
<TriggerActionForm
action={this.state.item.actions[this.state.actionIndex]}
index={this.state.actionIndex}
addNewAction={this.addNewAction}
editTriggerAction={this.editTriggerAction}
deleteTriggerAction={this.deleteTriggerAction}
editState={this.state.editState}
deleteState={this.props.actionState}
toggleEdit={this.toggleEdit}
activateEdit={this.activateEdit}/>
</div>
and here is the _onChange function of the grandchild TriggerActionForm
_onChange: function (e) {
e.preventDefault();
let newAction = assign({}, this.state.action);
const keyname = e.currentTarget.dataset.keyname;
if (keyname === "minDelay") {
newAction[keyname] = e.currentTarget.value;
} else {
newAction.args[keyname] = e.currentTarget.value;
}
this.setState({action: newAction});
if (!this.props.editState) {
this.props.activateEdit();
}
},
even when I unmount that component, the TriggerActionEntry state.item is modified, and shows up in the modified state when the component is mounted again...
UPDATE 2: OK, the problem is that neither Object.assign nor object-assign deeply clones objects. The classic! The actions were objects that were nested within item and rather than being cloned, another reference to the nested object was being created. Thanks for the help folks.
Im currently working on the same thing . The parent pass the data as a props to the children function. (im using hook instead of class). The purpose of the child component to process the data given from the parent and export as pdf or excel. Imagine the data pass in as an object that consists multiple array of objects . Each child object have an element of proj id which i would like to remove. The moment the data pass in , i have this
enter image description here
i set state with the data pass in from parent. When i gone throught some process and remove the the projid. When i try to access with any elements in the parent function. the whole thing gone broken.
I am trying to render and append a template (ticket_edit) to the body. I need to set a context to the newly appended template, and the events of ticket_edit should be bound to that template.
The code:
Template.ticket.events = {
'click a.edit' : function (event) {
//when the edit button has been clicked, load template 'ticket_edit'
//with the current context. Please see situation 1 and 2.
}
}
Template.ticket_edit.events = {
'click a.save' : function (event) {
//this won't do anything when i have supplied a context!
}
}
So the problem is:
-I can set the context, but then the events are not bound to the newly added template.
-If I don't set the context the events are bound properly.
But i need both the events and the context.
Situation 1:
'click a.edit' : function (event) {
//applying a context to the template will result in events not being bound.
$('body').append(Meteor.render(Template.ticket_edit(this)));
}
Sitation 2:
'click a.edit' : function (event) {
//this way, the events will execute properly and i can save my ticket.
//However, no context is supplied!
$('body').append(Meteor.render(Template.ticket_edit));
}
Does anybody have a good method for doing this? I'm fairly new to Meteor, so maybe you have a better method of dynamically loading templates.
Don't use jQuery for this, just do it directly with the template and a #with block. Something like this:
<body>
{{> tickets}}
</body>
<template name="tickets">
{{#each tickets}}
{{> ticket}}
{{/each}}
{{#with currentTicket}}
{{> editTicket}}
{{/with}}
</template>
Template.tickets.tickets = function() {
return Tickets.find();
};
Template.tickets.currentTicket = function () {
return Tickets.findOne({ _id: Session.get( "currentTicket" ) });
};
Template.ticket.events({
'click a.edit' : function () {
Session.set( "currentTicket", this._id );
}
});
Because we're using a #with block, the editTicket template won't get rendered until you click the edit button (setting the "currentTicket" in the Session).
It's also possible to just do this (no #with block):
{{> editTicket currentTicket}}
But that causes editTicket to always be rendered, just without any context until the Session var gets set.
Note that because we're using Session, the user won't be interrupted by reloads/hot code pushes.