Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何使用react transition group触发动画_Reactjs - Fatal编程技术网

Reactjs 如何使用react transition group触发动画

Reactjs 如何使用react transition group触发动画,reactjs,Reactjs,问题是我的表单有三种状态:错误、信息和成功。根据服务器的响应,我使用上述状态启动烤面包机,当服务器的响应可用时,我需要添加淡入淡出动画 toasterService.js import React, {useState} from 'react'; import {Transition} from 'react-transition-group'; import './toasterService.css' export default function ToasterService(

问题是我的表单有三种状态:错误、信息和成功。根据服务器的响应,我使用上述状态启动烤面包机,当服务器的响应可用时,我需要添加淡入淡出动画

toasterService.js

 import React, {useState} from 'react';
 import {Transition} from 'react-transition-group';
 import './toasterService.css'

 export default function ToasterService(content, timeout, style) {
const inProp = useState(true); // always call hook on top level
const duration = timeout;
const transitionStyles = {
    entering: {opacity: 1},
    entered: {opacity: 1},
    exiting: {opacity: 0},
    exited: {opacity: 0},
};

let defaultStyle = {};

switch (style) {
    case 'info' :
        defaultStyle = {
            transition: `opacity ${duration}ms ease-in-out`,
            opacity: 0,
            backgroundColor: '#00c5dc',
            color: '#ffffff'
        };
        break;

    case 'success' :
        defaultStyle = {
            transition: `opacity ${duration}ms ease-in-out`,
            opacity: 0,
            backgroundColor: '#8ebe4b',
            color: '#ffffff'
        };
        break;
    case 'danger' :
        defaultStyle = {
            transition: `opacity ${duration}ms ease-in-out`,
            opacity: 0,
            backgroundColor: '#FF0000',
            color: '#ffffff'
        };
        break;
    default :
}


return (<div className="main-alert">

        <Transition in={inProp} timeout={duration}>
            {state => (
                <div style={{
                    ...defaultStyle,
                    ...transitionStyles[state]
                }}>
                    {content}
                </div>
            )}
        </Transition>
    </div>

);
}

Toast服务收到3个参数,但烤面包机未出现。我缺少什么?

我最近自己构建了一个Toastr组件,它的基本功能是使用
样式化组件
动画
反应转换组
,这可能会帮助您正确使用它

注意:我认为使用
animejs
比为每个过渡阶段设置样式更容易。基本上,您可以获得进入或退出元素的引用,并使用
animejs
以您喜欢的方式对其设置动画

react transition group
将为您提供这些道具中元素的参考:

<Transition
  key={item.id}
  onEntering={animateEnter}  // animateEnter will have a reference to the element
  onExiting={animateExit} // animateExist will have a reference to the element
  timeout={{
    enter: 500,
    exit: 500
  }}
  unmountOnExit={true} // I was testing, but I don't think this prop is necessary in my component
>
SomeComponent.js(将发出祝酒声)

import React,{useContext}来自“React”;
从“/ToastrContext”导入到astrcontext;
从“样式化组件”导入样式化;
函数SomeComponent(){
const sendtoos=useContext(ToastrContext);
返回(
嘿!点击来祝酒!
sendToast(“这是你的吐司!”)}>单击
);
}
导出默认组件;
<Transition
  key={item.id}
  onEntering={animateEnter}  // animateEnter will have a reference to the element
  onExiting={animateExit} // animateExist will have a reference to the element
  timeout={{
    enter: 500,
    exit: 500
  }}
  unmountOnExit={true} // I was testing, but I don't think this prop is necessary in my component
>
import React from "react";
import ReactDOM from "react-dom";
import Toastr from "./Toastr";
import SomeComponent from "./SomeComponent";

import "./styles.css";

function App() {
  return (
    <Toastr>
      <SomeComponent />
    </Toastr>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
import React, { useRef, useEffect, useState } from "react";
import styled from "styled-components";
import { TransitionGroup, Transition } from "react-transition-group";
import anime from "animejs";
import ToastrContext from "./ToastrContext";

// CREATE A USE TOASTER HOOK ?
// MAYBE CREATE AN APP STATE TO STORE THE TOASTS

const S = {};

S.FixedContainer = styled.div`
  position: fixed;
  bottom: 10px;
  /* right: 5px; */
  /* left: 0; right: 0; */
  /* CENTER IT HORIZONTALLY */
  left: 50%;
  transform: translateX(-50%);
`;

S.ToastContainer = styled.div`
  width: 300px;
  height: 64px;
  margin-top: 10px;
  margin-bottom: 10px;
  /* padding-left: 10px; */
  color: white;
  font-weight: bold;
  background: #39c16c;
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
`;

function Toastr(props) {
  const lastToastLengthRef = useRef(0);
  const [toasts, setToasts] = useState([]);
  const toastID = useRef(0);

  console.log("Toastr rendering...");
  console.log(toasts);

  function addNewToast(toast) {
    setToasts(prevState => {
      const aux = Array.from(prevState);
      aux.push({ msg: toast, id: toastID.current });
      toastID.current = toastID.current + 1;
      return aux;
    });
  }

  useEffect(() => {
    if (toasts.length > lastToastLengthRef.current) {
      console.log("useEffect: Toast was added...");
      // TOAST WAS ADDED
      setTimeout(() => {
        setToasts(prevState => {
          const aux = Array.from(prevState);
          aux.shift();
          return aux;
        });
      }, 1000);
      lastToastLengthRef.current = toasts.length;
      return;
    }
    lastToastLengthRef.current = toasts.length;
  }, [toasts]);

  function animateEnter(element) {
    anime({
      targets: element,
      opacity: 0,
      duration: 0
    });
    anime({
      targets: element,
      opacity: 1,
      easing: "easeOutExpo",
      duration: 2000
    });
  }

  function animateExit(element) {
    anime({
      targets: element,
      opacity: 0,
      easing: "easeOutExpo",
      duration: 2000
    });
  }

  // const toastItems = toasts.map((item,index) =>
  //   <S.ToastContainer key={item.id}>{item.msg}</S.ToastContainer>
  // );

  const toastItems = toasts.map((item, index) => (
    <Transition
      key={item.id}
      onEntering={animateEnter}
      onExiting={animateExit}
      timeout={{
        enter: 500,
        exit: 500
      }}
      unmountOnExit={true}
    >
      <S.ToastContainer>{item.msg}</S.ToastContainer>
    </Transition>
  ));

  return (
    <React.Fragment>
      <S.FixedContainer>
        <TransitionGroup component={null}>{toastItems}</TransitionGroup>
        {/* {toastItems} */}
      </S.FixedContainer>
      <ToastrContext.Provider value={addNewToast}>
        {props.children}
      </ToastrContext.Provider>
    </React.Fragment>
  );
}

// Toastr.whyDidYouRender = true;

export default Toastr;
import React from "react";

const ToastrContext = React.createContext(null);

export default ToastrContext;
import React, { useContext } from "react";
import ToastrContext from "./ToastrContext";
import styled from "styled-components";

function SomeComponent() {
  const sendToast = useContext(ToastrContext);

  return (
    <React.Fragment>
      <div>Hey! Click for some toasts!</div>
      <button onClick={() => sendToast("This is your toast!")}>Click</button>
    </React.Fragment>
  );
}

export default SomeComponent;