I want to make custom confirmation modal whenever user wants to delete his own post. How to approach that to use as less as possible code? I was thinking about independent component with logic inside (user can send via props function on yes/no, etc) but the problem I can't figure out is how to mount this component when user click on a button? Do I need to use local state inside every component when I need to use modal? Something like:
showModal ? <Modal onYes={()=>{}} onNo={()=>{}} title='whatever you want' /> : ''
Can I achieve that in other way? I hope I explained well.
You can use HOC as well. Keep show/hide state inside HOC and then pass props/functions (with currying) from Parent component
Small example - https://codesandbox.io/s/withtoggle-hoc-8bd0r
Related
This question is related to this one. I am rewording to make it simple.
I have a main navigation component (MainNavigation.js) which is siblings with a Secondary Navigation Component(SecNavigation.js) under the Header component(Header.js).
What I want is when I click on a specific Link in the MainNavigation.js the whole SecNavigation.js to be displayed in a modal.
My problem here is that I don't quite grasp how should I go using useState, useContext or even if I need any of this.
Hope this will clear something for you
What you need is a parent that handles the state and then it will pass it down to its children. Because the parent is keeping track of the children and what they are doing.
So what I have done it this:
App.js is the parent and I handle the state here.
Then I just pass down the setIsModalShowing setState function to the MainNav that will call it when I press a button.
Then in the App.js I will show or hide the modal if the setIsModalShowing is true or false
inside of the modal I am showing SecNav and the modal also has the setIsModalShowing passed down so that you can click on the button to close is and that will set the state to false.
Does that makes sense to you ? or else I can try to explain it in another way
Code example
I've looked up whole google for my answer (haha).
What I am trying to achieve:
My fist screen is a form with some input fields which store the input to state.
By clicking "submit" the user comes to the next page/screen, where the previous input is supposed to show up. I want to show only the input data as a p-tag, not as an input tag anymore.
How do I achieve this? I am bloody new to reactjs.
I've thought about multiple solutions:
store the input data to an external JSON (which seems pretty complicated)
pass the data as props, but I am not aware of how I would do this
Thanks so far!
I'm going to assume that your second screen has the same parent component as your first, something like this:
render() {
return (
<div>
{this.state.showFirstScreen && <FirstScreen />}
{this.state.showSecondcreen && <Secondcreen />}
</div>
)
}
If that's the case, your FirstScreen component can accept a prop called something like onSubmit -- you say that you already store the input values from FirstScreen in state, so when FirstScreen is finished, you can call this.props.onSubmit(this.state) and it will send up the state to your parent component, as long as you've defined a callback function in the parent component:
{this.state.showFirstScreen && <FirstScreen onSubmit={this.onFirstScreenSubmit} />}
Then, you can save the state of the first screen into the state of your Parent component, and pass that part of the state down to SecondScreen
[edit] here's a very crude example: https://jsfiddle.net/df4s9ey8/
I have the component that displays one button. Clicking this button loads the component which has a back button. I now want to return back to the component when this back button is clicked.
I am new to react and if I search online I see react-routing as the solution. Wouldn't simply rendering the component from component work? Just like was rendered from ?
Parent component has a state named isChildActive.
this.state = {isChildActive: false}
On the render of Parent you instantiate <ChildComponent active={this.state.isChildActive} goBack={() => this.setState({isChildActive: false})} />
And then you add to the onClick callback of the button at ParentComponent: <button onClick ={() => this.setState({isChildActive:true})} />
So that's the simple way of doing it. You own the state at your parent component because in react, data flows unidirectionally, from top to bottom. And then you pass a callback to your children components, to modify that parent owned state, when needed.
The best way of routing is using a library because it is not a simple task and you'll save a lot of time and headaches if you use a well-tested library. The industry standard is react-router
Consider a VueJS app that allows for showing / editing blogposts.
On clicking "edit blogpost" a modal (Vue component) is shown to edit the current blogpost (just an ordinary js-object).
To this end I pass the current blogpost as a prop to the modal-component.
The Modal component has a couple of form fields that should be populated with the blogpost-attributes.
However, the Vue 'way' is to have a data object on the Modal-component that acts as the model to populate the form fields, and vice-versa, be updated when the user changes the form fields.
The problem: How do I connect the blogpost which is passed as a prop to the data field of the modal-component so that:
the blogpost populates the form fields
the blogpost gets updated when updating the form fields
What's the correct Vue way to accomplish this?
You have three (at least) ways of doing it:
1) Connect the data via the prop attribute, just as you are doing, but add the .sync attribute to it. This way, when the data is modified on the form, it automatically gets modified too on the component. The problem with this solution is that the update is automatic, so if a validation fails, or the user closes the modal without saving the changes, these are saved anyway. An example: https://jsfiddle.net/Lz3aq64f/
2) The other way of doing it is getting the modal to $dispatch an event with the saved information when it's saved. The blogpost element should listen for this event and act accordingly.
On the modal:
this.$dispatch('update-post', this.title, this.author);
On the blogpost:
this.$on('update-post', function(title, author) {
this.title = title;
this.author = author
});
If the blogpost component and the modal component are not in the same hierarchy, things get a little bit more complicated, and probably you need the common parent element to act as a proxy. Think of the modal element dispatching the information up, the #app element catching it via $on, and then doing $broadcast to the blogpost element.
3) Use something like vuex to act as a central repository of state. I don't know how big is your application, but this would be the cleanest way to go: http://vuex.vuejs.org/en/index.html
Good luck!
Hi I want to hide an adf component automatically.I have a selectOneChoice that contain some number (from 1 to 12).
Example when I select 2, it show's two field automatically without clicking any button..
i used this function to hide a declared componenet but just when i click a button..
function enableField(actionEvent) {
var nameInputText = actionEvent.getSource().findComponent("soc1");
nameInputText.setProperty("visible", true);
actionEvent.cancel();
}
i set the componement "soc1" visible = true than through the javascript function i change it..
SO the probleme here is how to read the number from the selectonechoise and how to set the component visible directly without clicking any button.
Actually Rendered won't do what you want. You want to use Visible property instead. Rendered causes the actual markup for the component not to be rendered on the page, so a Partial Refresh will not cause it to appear. Rendered is reserved, usually, to hide items that are secure. We set rendered property to false on the item(s), but then refresh the parent containing component - usually a layout manager - then it works. So either refresh the layout manager that contains the item or use Visible. I demonstrated this exact use case last week in class and it works as described.
Basicaly, you don't need javascript solution or any programming to achieve this.
You should set attributes rendered(this way component won't be rendered at the page at all) and partialTriggers that points to selectOneChoice component for components you want to show or hide. Also you have to set autoSubmit="true" for your selectOneChoice component.
<af:selectOneChoice id="soc1" autoSubmit="true" .../>
<af:panelGroupLayout id="plg1" partialTriggers="soc1">
<af:outputText id="ot1" rendered="#{bindings.lov.inputValue le 1}" inputValue="text1"/>
</af:panelGroupLayout>
Note: its not working code, just a sample
It will work following way, on valueChange event at selectOneChoice component value is submitted and partialRefresh fires for components that have it in partialTriggers specified. And rendered attribute will either render or remove component depending on it's EL expression. Components that should be managed wrapped into another component to make sure PPR reach it when they ain't rendered.