React animate leaving div content - reactjs

I'm using React and React-Spring to animate a questionnaire app.
I want the questionnaire to animate the leaving/enter of a question when the user answer one.
I'm using React for the app and try to use React-Spring to animate the transitions. The issue is that when the user is answering a question, the question component is updated with the new content before it leaving.
To simplify it, the Question component look like this:
export default function Question({question, onAnswer}) {
const [answer, setAnswer] = useState(null);
return (
<animated.div ...>
{question.title}
<select>...{quesiton.options}...</select>
<button onClick={() => onAnswer(question.id, answer)}>Next</button>
</animated.div>
);
}
I create a Code Sandbox that illustrates my issue:
https://codesandbox.io/s/nostalgic-swartz-lhkj0?file=/src/AnimatedComponent.js
How should I handle this? couldn't find any example on the web
Thanks!

You should use the item property in the transition map instead of using the text directly in the animated.div.
{transitions.map(
({ item, key, props }) =>
item && (
<animated.div key={key} style={props}>
{item}
</animated.div>
)
)}

Related

`Popover` (as React component) with `OverlayTrigger`

I'm trying to create rich React component as popover content.
If I use example with simple const popover (https://react-bootstrap.netlify.app/components/overlays/#examples-1) everything works fine.
Problem
But custom react component fails to position itself. It appears on top left of the screen
const MyPopover = React.forwardRef((props, ref) => {
return <Popover ref={ref} placement={"bottom"}>
<Popover.Header as="h3">
<Form.Control></Form.Control>
</Popover.Header>
<Popover.Body>
<strong>Holy guacamole!</strong> Check this info.
</Popover.Body>
</Popover>
})
const PopoverChooser = ({children, container}) => {
const _refTarget = useRef(null)
return <>
<OverlayTrigger
trigger="click"
placement="bottom"
overlay={<MyPopover ref={_refTarget}/>}
target={_refTarget.current}
>
{children}
</OverlayTrigger>
</>
}
export default PopoverChooser;
As you can see, I'v tried to use ref's, but it's doesn't help.
Question
How can it link popover to target button (in image as dropdown button and in code as {children}).
Or should I position MyPopover manually (by checking button ID and assigning position.. etc.?)
Completely different approach to dig in..?
Your approach to forward the ref was right. What you actually forgot is to also inject props. According to the documentation:
The and components do not position themselves.
Instead the (or ) components, inject ref and
style props.
https://react-bootstrap.netlify.app/components/overlays/#overview
So what you need to do is to spread the props like this:
const MyPopover = React.forwardRef((props, ref) => {
return (
<Popover ref={ref} {...props}>
https://codesandbox.io/s/trusting-sid-0050g9

Two instances of the same element seem to share state

In my React application I have a Collapsible component that I use more than once, like so:
const [openFAQ, setOpenFAQ] = React.useState("");
const handleFAQClick = (question: string) => {
if (question === openFAQ) {
setOpenFAQ("");
} else {
setOpenFAQ(question);
}
};
return ({
FAQS.map(({ question, answer }, index) => (
<Collapsible
key={index}
title={question}
open={openFAQ === question}
onClick={() => handleFAQClick(question)}
>
{answer}
</Collapsible>
))
})
And the Collapsible element accepts open as a prop and does not have own state:
export const Collapsible = ({
title,
open,
children,
onClick,
...props
}: Props) => {
return (
<Container {...props}>
<Toggle open={open} />
<Title onClick={onClick}>{title}</Title>
<Content>
<InnerContent>{children}</InnerContent>
</Content>
</Container>
);
};
However, when I click on the second Collapsible, the first one opens... I can't figure out why.
A working example is available in a sandbox here.
You will need to ensure that the label and id for each checkbox is the same. Here's a working example
But if you're trying to implement an accordion style, you may need another approach.
on Collapsible.tsx line 36, the input id is set the same for both the Collapsibles. you need to make them different from each other and the problem would be solved.
One thing is that you have the same id which is wrong BUT it can still work. Just change the checkbox input from 'defaultChecked={...}' to 'checked={...}'.
The reason is that, if you use defaultSomething - it tells react that even if this value will be changed - do not change this value in the DOM - https://reactjs.org/docs/uncontrolled-components.html#default-values
Changing the value of defaultValue attribute after a component has mounted will not cause any update of the value in the DOM

Couldn't find draggable element with id using react-beautiful-dnd

I have been trying to implement a drag and drop functionality using the react-beautiful-dnd library.
I am displaying some buttons from the initial state of redux and trying to make those items draggable.
But, for some reasons,I am having an error in console saying that "Unable to find draggable element with id: " when trying to move the button elements. This is for the first time,I am trying to implement such functionalities and not sure where I have done the mistake. I know that the Droppable wrapper should have a droppableId but based on the structure of my state data, how can I pass the id?
Here is my, ListItems components that I have modified to use the drag and drop logic:
import React from "react";
import { connect } from "react-redux";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
const ListItems = props => {
const onDragEnd = result => {
console.log("drag end");
};
return (
<DragDropContext onDragEnd={onDragEnd}>
<div>
List Items
<Droppable>
{provided => (
<div innerRef={provided.innerRef} {...provided.droppableProps}>
{props.items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{provided => (
<div
className="user-lists"
key={item.id}
{...provided.draggableProps}
{...provided.dragHandleProps}
innerRef={provided.innerRef}
>
<button>{item.name}</button>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</div>
</DragDropContext>
);
};
const mapStateToProps = state => ({
items: state.items.buttons
});
export default connect(
mapStateToProps,
{}
)(ListItems);
and then the ListItems component is used in App component.
For complete demo here is the sandbox link:
https://codesandbox.io/s/adoring-jones-roswh?file=/src/components/ListItems.js:0-1298
So, I fixed that problem and draggbale is working accordingly. But, now the problem is that I can't move the item by clicking or selecting the button elements rather I need to drag the button from the right side. probably because of the div element that wraps the buttons are handling the dragging. Any fixes to make the buttons draggable, would be nice..

Having trouble with onMouseEnter event in React

I'm trying to build a navbar, using React and hooks, where each div will change to a specific color on an onMouseEnter and onMouseLeave. I can't figure out why they're all affected if i hover over one. I guess I'm asking how I could make them independent of one another.
Sorry if this is a really obvious mistake. Still really green. Thanks again!
Here is a link to the CodeSandbox: https://codesandbox.io/s/holy-snowflake-twojb?file=/src/navbar.js
I refactored your code.
You can check it in https://codesandbox.io/s/lucid-lake-u3oox?file=/src/navbar.js
You are using the function setBackground to set the background color in the hoverStyle CSS class which affects to all <div className="hoverStyle"> tags.
There are many options to do that. If you want to do it with React, one way of do it is creating a CSS class like this:
.active {
background-color: #ffac4e;
}
then, create a functional component
const Activable = ({ className, children, bgColor}) => {
const [active, setActive] = useState('#fff');
return (
<div className={`${ className } ${ active }`
onMouseEnter = {() => setActive( bgColor )}
onMouseLeave = {() => setActive('#fff')}
>
{ children }
</div>
)
}
then replace your ` with this new component like this:
<Activable className="hoverStyle" bgColor="#ffac4e">
<div style = {navChildLeft}>2020</div>
<div style = {navChildTop}>
Shy RL <br />
Digital - Album art
</div>
</Activable>
and repeat with the rest of <div>'s
With react, it is important to think about reusable components. How can you create something that you can reuse over and over again in different parts of your project.
Take a look at this sample of your project broken into components.
https://codesandbox.io/s/holy-brook-3jror?fontsize=14&hidenavigation=1&theme=dark
I would recommend reading this to help out: https://reactjs.org/docs/thinking-in-react.html

using react-autosuggest with react-custom-scrollbars

is it possible to use react-custom-scrollbars with react-autosuggest together?
I wrote this in for auto-suggest but it doesn't work correctly:
renderSuggestionsContainer({ containerProps, children, query }) {
const callRef = scrollbars => {
if (scrollbars !== null) {
ref(scrollbars);
}
}
return (
<Scrollbars
autoHeight
autoHeightMax={240}
id={this.props.id}
ref={callRef}
renderTrackVertical={() => <div className="scrollbars-wrapper" />}
renderThumbVertical={() => <div className="scrollbar-handler" />}>
{children}
</Scrollbars>
);
}
How?
if want to implement react js auto-suggestion box, then you can simply use "react-select", have all feather like scrolling, loader etc.
you will find more detail here https://github.com/JedWatson/react-select
if you want to implement your own with react-native
then instead of scrollbar you should use ListView, because it having more feather-like,
Auto-caching image for ios and android,
Method for onReachBottom which helps to implement infinite scroll. etc

Resources