I have a file, app.js, which contains some React code. The code producess something like a rudimentary kanban board. Right now, the user can create a new div for the board, and then edit or drag the div into a column. However, the state is not preserved if the div has been edited before dragging across columns; the div contents will disappear.
I have tried editing the code in the returned div, modifying the isContentEditable property, but to no avail; the state is lost, and the entered content dissapears, leaving an empty div.
For reference, here is the code in a sandbox:
https://codesandbox.io/s/sweet-feather-80261
All help is appreciated, total noob to front end development!
Try using the useState hook for functional components, or look into Redux to implement global state!
Redux will allow you to have state that can be changed and used by multiple components.
Related
So, I am creating a customizing tool for cursors with Vuejs and Vuex. Currently, I am stuck in the step where I have to bind a color user is going to click on to the fill of svg cursor. I will try to cover step by step how everyhing works and what it should do.
First of all, I have different inline SVG's which are replacing the default HTML cursor. These SVG's are placed in the Vuex state.
Just so you know they are put like this so when the user clicks on a button on the first component, script hides default cursor and binds chosen one with V-HTML. Basically, I am displaying them as HTML code in the components.
This is where the issue begins. Now, this chosen cursor displays on the second component where the user should be able to change the fill color.
What I can't figure out is how can I access the property of fill in the svg's?
I have tried to bind it via :fill = "dataName" but it doesn't work like that.
I am new to Vuejs but I hope my question makes sense.
The problem is that you're inserting the inline SVG (via v-html) after the Vue compilation step, so — as you've noticed — Vue never sees that content. Without more context, it's hard to see how you could achieve what you want.
As an alternative, though, you could have all your cursors use currentColor for the fill color
<path fill="currentColor">
and then simply set the CSS color property of some containing element to the desired color
I created a layout component for my react app, and I wanted to dynamically update the side bar and navigation bar on route change.
I can use redux, but all of the state and methods will be available at all times, even if i don't need them.
I also looked at the new react context, but it has the same problem as redux.
With react router, it looks like i'm just mounting a new sidebar or navigation bar.
Is there a way to dynamically provide new state and methods to my layout component?
(replace the state with a different one, or multiple new once: apple --> orange)
React router looks like my best option, but I can do the same thing by just including the sidebar and navigation bar with each new route.
Dynamically adding links is not a problem, adding a button that affects the newly mounted component is the problem. The navigation bar and side bar lives in the parent component, so they need to know all of the states and methods.
Thanks,
Edit:
Example:
- Home - About - Contact
No problem, with link. I can just replace the link components with any other component with a switchComponet method.
Stop - Speed-Up - Help
These are all buttons. Now I need to add their methods and state to the Layout component. Is the app grows, more state and methods will need to be added to the top component.
I can place all of them in redux, but all the state and methods are always available. I probably have the wrong impression about redux, I'm thinking that it might take up a lot of resources, but I might be wrong.
My guess is that by "state and methods" you mean the mapStateToProps and mapDispatchToProps arguments of the react-redux connect function in your layout component.
If that's the case then you have reasons to be concerned about putting the logic of all possible content of your layout in there.
I think your problem is that you're assuming that you have to connect only the top container to redux when it's not the case.
You can connect your layout component to deal with the nav and side bar and at the same time having components nested in your layout component and connected to redux with their own store keys (part of the store state) and actions.
This way you don't need to add all store states and action needed for each layout content. Each layout content will stay close to its logic.
That's actually one of the purposes of redux.
So I have an app that has a right sidebar whose visibility is toggled via a button. In that sidebar there can be one of several things [at a time] - chat, help, search. I was looking at some plain HTML from apps which have a similar feature and noticed that they have all nodes rendered, but are just hidden via CSS.
Since I need to do the same thing, I was thinking whether this would be a good idea to do with React. But then I realized that React elements have a state which when updated calls the render method. So I can use the state to store both whether the sidebar is opened, and what is inside the sidebar.
Is that the React way of doing things? Is it better to have all nodes rendered even if they are not visible, or is it better to have the nodes rendered on request via state changes?
My feeling is that only rendering what is visible would be the more standard React way, but in this case, this is mainly a performance decision. If you render everything and just toggle visibility with CSS, the first render will take longer (but the time difference may not be relevant or even noticeable). If you render only the part that's visible, React needs to do a small rerender every time the sidebar content changes. (This may also not be noticeable time.)
My recommendation would be to try both, if you want to test the performance. But I think you won't go too wrong either way.
Suppose we have two sibling react components called OldContainer and NewContainer. There is a child component inside OldContainer that contains a <video> tag, and the video is currently playing.
The user can now drag the child component (with the video) and drop it in the NewContainer, and they expect the video to keep playing while it's being dragged and after being dropped.
So the video appears to stick to the mouse position, and when dragged and dropped in the new container, it animates to its new position (again, it doesn't get paused).
How would you implement this? Can we implement this in a pure way (in line with the spirit of pure functions)?
Clarification: I could have used some other element instead of a video tag for explaining this problem. A NumberEasing element would be a better example, since it would require the props and state of the component to be preserved during and after the interaction.
Update 1: Code examples obviously would be nice, but what I'm mainly looking for is just a general description of how you would approach this problem in a "functional" way. How do you keep your view code simple and easy to reason about? Who handles the drag-and-drop gesture? How do you model the data that's fed into the views?
Take a look at this library : react-reverse-portal
What is it that you want to preserve? Is it Javascript objects that the component holds as state, or is it state in the DOM (like how long a video has played, or text selection in an input box)?
If it's just Javascript objects as state, you're better of moving the source of that state to another service (something like Flux). That way, it doesn't matter if the component gets recreated because it can be recreated with the state that was there before.
EDIT
The way to keep your view code simple and easy to reason about is to not keep state inside your components. Instead, all data that the component needs should be passed into the component as props. That way, the component is "pure" in that it renders the same output given the same props. That also makes the problem of wanting to reuse a component instance a non-issue, since it doesn't matter when the same input gives the same output.
For drag and drop, I'd suggest looking at: https://github.com/gaearon/react-dnd.
How you model the data you pass to view components is up to you and the needs of your application. The components shouldn't care, they should just expect to get data passed as props, and to render them. But the popular approach to dealing with this is of course Flux, and there are many libraries that implements Flux in different ways.
SECOND EDIT
Regarding if you have a subtree with hundreds of components that you want to move: I'd still start off by making the state external (pure components), and render that tree in a new place. That means that React will probably recreate that entire subtree, which is fine. I wouldn't deviate from that path unless the performance of it turned out to be horrible (just guessing that it might be horrible isn't enough).
If the performance turned out to be horrible, I would wrap that entire subtree in a component that caches the actual DOM tree and reuses it (if it gets passed the same props). But you should only do this when absolutely needed, since it goes against what React tries to do for you.
THIRD EDIT
About gestures: I'd start out with listening to gesture events in componentDidMount, and in the event callback call setState on the component with the coordinates it should have. And then render the component in render with the coordinates given. React won't recreate the component when you call setState but it will re-render it (and diff the output). If the only thing you changed was the coordinates, it should render fast enough.
If that turns out to be too slow, like if the subtree of that component is huge and it becomes a bottleneck to recreate the subtree of vDOM, I'd reposition the DOM node directly in a RAF-loop outside of Reacts control. And I'd also put a huge comment on why that was needed, because it might seem wierd for some other developer later.
Create a new variable using const or var. Put the instance of data using rest spread operator, update the necessary data to pass and send the data to the component without mutating the state of component.
Just like:
const data = {
...this.state.child,
new_data : 'abc'
}
I currently have an app that has five components. On the left I have a radio button field and a grid below it, on the right I have a display field, chart, and another grid [top to bottom]. The radio buttons filter every other component by a certain date, and the left grid [when selected] will filter the right components by the selected object.
Currently the app does what is needed, but when I select a few radio buttons in a row OR select a few objects in the grid, the app will eventually totally disappear. I tried running the app externally and internally with a custom HTML app, but the problem does not go away.
Here is a picture of the app before anything crashes:
Interestingly, when I look through the chrome debugger and look at the Elements tab, I see there are lots of masks that have been created and not destroyed. Here is a picture of a slight piece of the HTML that looks fishy and occurs after I select a few objects from the left grid:
Every time I select a new object, one more mask will be added to the DOM. I don't know if this is what breaks my app, but it seems odd so it may be related?
I didn't include any code because I thought it should be some easy fix - plus, the code does exactly what it should [before it disappears]. Any help on how to fix an app that disappears would be great!
In itself a mask sticking around to be reused after data loaded successfully is not an indication of a problem. I see mask being created and not destroyed in a simpler app:
Perhaps what you experience is an issue of timing when elements load asynchronously.