প্রতিক্রিয়া - একক উপাদানটির মাউন্ট এবং আনমাউন্ট সঞ্চার করুন


103

এই সাধারণ কিছুটি সহজেই সম্পন্ন করা উচিত, তবুও আমি কতটা জটিল তার উপর আমার চুল টানছি।

আমি যা করতে চাই তা হ'ল একটি প্রতিক্রিয়া উপাদানটির মাউন্টিং এবং আনমাউন্টিং, এটিই। আমি এখন পর্যন্ত যা চেষ্টা করেছি তা এখানে এবং প্রতিটি সমাধান কেন কাজ করবে না:

  1. ReactCSSTransitionGroup - আমি মোটেও CSS ক্লাস ব্যবহার করছি না, এটি সমস্ত জেএস স্টাইল, সুতরাং এটি কাজ করবে না।
  2. ReactTransitionGroup- এই নিম্ন স্তরের এপিআই দুর্দান্ত, তবে অ্যানিমেশনটি সম্পূর্ণ হওয়ার পরে আপনার কলব্যাক ব্যবহার করা দরকার, তাই কেবল সিএসএস রূপান্তরগুলি ব্যবহার করে এখানে কাজ করবে না। এখানে সবসময় অ্যানিমেশন লাইব্রেরি থাকে যা পরবর্তী পয়েন্টে নিয়ে যায়:
  3. গ্রিনসক - ব্যবসায়ের ব্যবহার আইএমওর জন্য লাইসেন্সিং খুব সীমাবদ্ধ।
  4. প্রতিক্রিয়া গতি - এটি দুর্দান্ত বলে মনে হচ্ছে তবে TransitionMotionএটি আমার যা প্রয়োজন তা অত্যন্ত বিভ্রান্তিকর এবং অতিরিক্ত জটিল।
  5. অবশ্যই আমি কেবল ইউটিরিয়াল ইউআইয়ের মতো কৌতূহলী করতে পারি, যেখানে উপাদানগুলি রেন্ডার করা হয় তবে লুকানো থাকে ( left: -10000px) তবে আমি বরং সেই পথে যাব না। আমি এটিকে হ্যাকি হিসাবে বিবেচনা করি এবং আমি চাই আমার উপাদানগুলি আনমাউন্ট করা যাতে তারা পরিষ্কার হয় এবং ডমকে বিশৃঙ্খলা না করে।

আমি এমন কিছু চাই যা কার্যকর করা সহজ । মাউন্টে, শৈলীর একটি সেট প্রাণবন্ত করুন; আনমাউন্টে, একই (বা অন্য) শৈলীর সেট অ্যানিমেট করুন। সম্পন্ন. এটি একাধিক প্ল্যাটফর্মে উচ্চ পারফরম্যান্সও করতে হবে।

আমি এখানে একটি ইটের প্রাচীর আঘাত করেছি। যদি আমি কিছু মিস করছি এবং এটি করার সহজ উপায় আছে তবে আমাকে জানান।


এখানে আমরা কী ধরণের অ্যানিমেশন বলছি?
প্রাণেশ রবি

শুধু কিছু সহজ, একটি CSS এর অস্বচ্ছতা বিবর্ণ এবং মতtransform: scale
ffxsam

পয়েন্ট 1 এবং 2 আমাকে বিভ্রান্ত করে। আপনি কোন ধরণের অ্যানিমেশন ব্যবহার করছেন? জেএস রূপান্তর বা সিএসএস রূপান্তর?
প্রণেশ রবি

4
সিএসএস শৈলী / শ্রেণিগুলি (যেমন .thing { color: #fff; }) জেএস স্টাইলগুলি ( const styles = { thing: { color: '#fff' } }) দিয়ে বিভ্রান্ত করবেন না
ffxsam

তবে সমস্যাটি হ'ল যখন আপনি জাভাস্ক্রিপ্ট ব্যবহার করে স্টাইলটি পরিবর্তন করার চেষ্টা করবেন আপনি আসলে এমন কোনও উপাদানের স্টাইলটি প্রতিস্থাপন করছেন যা কোনও রূপান্তর দেয় না।
প্রণেশ রবি

উত্তর:


104

এটি কিছুটা লম্বা তবে আমি এই অ্যানিমেশনটি অর্জনের জন্য সমস্ত নেটিভ ইভেন্ট এবং পদ্ধতি ব্যবহার করেছি। না ReactCSSTransitionGroup, ReactTransitionGroupএবং ইত্যাদি

জিনিস আমি ব্যবহার করেছি

  • জীবনচক্র পদ্ধতি প্রতিক্রিয়া
  • onTransitionEnd ইভেন্ট

এটি কীভাবে কাজ করে

  • মাউন্ট প্রোপ পাস ( mounted) এবং ডিফল্ট শৈলী ( opacity: 0) এর সাথে ভিত্তি করে উপাদানটি মাউন্ট করুন
  • মাউন্ট বা আপডেটের পরে, টাইমআউট (এ্যাসিঙ্ক করতে) এর সাথে শৈলী ( ) পরিবর্তন করতে componentDidMount( componentWillReceivePropsআরও আপডেটের জন্য) ব্যবহার করুন opacity: 1
  • আনমাউন্ট চলাকালীন, আনমাউন্ট শনাক্ত করতে উপাদানটি একটি প্রস্তাব দিন, আবার শৈলীর পরিবর্তন করুন ( opacity: 0), onTransitionEndডিওএম থেকে উপাদানটিকে আনমাউন্ট করুন।

চক্র চালিয়ে যান।

কোডটি দেখুন, আপনি বুঝতে পারবেন। যদি কোন ব্যাখ্যা প্রয়োজন হয়, একটি মন্তব্য দয়া করে।

আশাকরি এটা সাহায্য করবে.

class App extends React.Component{
  constructor(props) {
    super(props)
    this.transitionEnd = this.transitionEnd.bind(this)
    this.mountStyle = this.mountStyle.bind(this)
    this.unMountStyle = this.unMountStyle.bind(this)
    this.state ={ //base css
      show: true,
      style :{
        fontSize: 60,
        opacity: 0,
        transition: 'all 2s ease',
      }
    }
  }
  
  componentWillReceiveProps(newProps) { // check for the mounted props
    if(!newProps.mounted)
      return this.unMountStyle() // call outro animation when mounted prop is false
    this.setState({ // remount the node when the mounted prop is true
      show: true
    })
    setTimeout(this.mountStyle, 10) // call the into animation
  }
  
  unMountStyle() { // css for unmount animation
    this.setState({
      style: {
        fontSize: 60,
        opacity: 0,
        transition: 'all 1s ease',
      }
    })
  }
  
  mountStyle() { // css for mount animation
    this.setState({
      style: {
        fontSize: 60,
        opacity: 1,
        transition: 'all 1s ease',
      }
    })
  }
  
  componentDidMount(){
    setTimeout(this.mountStyle, 10) // call the into animation
  }
  
  transitionEnd(){
    if(!this.props.mounted){ // remove the node on transition end when the mounted prop is false
      this.setState({
        show: false
      })
    }
  }
  
  render() {
    return this.state.show && <h1 style={this.state.style} onTransitionEnd={this.transitionEnd}>Hello</h1> 
  }
}

class Parent extends React.Component{
  constructor(props){
    super(props)
    this.buttonClick = this.buttonClick.bind(this)
    this.state = {
      showChild: true,
    }
  }
  buttonClick(){
    this.setState({
      showChild: !this.state.showChild
    })
  }
  render(){
    return <div>
        <App onTransitionEnd={this.transitionEnd} mounted={this.state.showChild}/>
        <button onClick={this.buttonClick}>{this.state.showChild ? 'Unmount': 'Mount'}</button>
      </div>
  }
}

ReactDOM.render(<Parent />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>


এর জন্য ধন্যবাদ! আপনি কোথায় শিখলেন onTransitionEnd? আমি প্রতিক্রিয়া দস্তাবেজে এটি দেখতে পাচ্ছি না।
ffxsam 21

@ffxsam ফেসবুক. github.io/react/docs/events.html এটি রূপান্তর ইভেন্টগুলির অধীনে।
প্রণশ রবি

4
এটি কী কীভাবে আপনি কীভাবে জানলেন, ডকুমেন্টেশনের কোনও ব্যাখ্যা নেই। আরেকটি প্রশ্ন: আপনি কীভাবে componentWillReceivePropsকিছু ফিরিয়ে দিতে পারবেন জানেন ? আমি এর উপর আরও কোথায় পড়তে পারি?
ffxsam

4
@Fffsam onTransitionEnd একটি স্থানীয় জাভাস্ক্রিপ্ট ইভেন্ট। আপনি এটি সম্পর্কে গুগল করতে পারেন। ফেসবুক.github.io/react/docs/… আপনাকে উপাদানবিশেষগ্রহীতাপ্রসারণ সম্পর্কে ধারণা দেবে।
প্রণেশ রবি

7
বিটিডাব্লু আমি মনে করি আপনার কোডটিতে একটি ভুল আছে। আপনার Parentউপাদানগুলিতে, আপনি উল্লেখ করেছেনthis.transitionEnd
ffxsam

15

প্রণেশের উত্তর থেকে প্রাপ্ত জ্ঞানকে ব্যবহার করে আমি একটি বিকল্প সমাধান নিয়ে এসেছি যা কনফিগারযোগ্য এবং পুনরায় ব্যবহারযোগ্য:

const AnimatedMount = ({ unmountedStyle, mountedStyle }) => {
  return (Wrapped) => class extends Component {
    constructor(props) {
      super(props);
      this.state = {
        style: unmountedStyle,
      };
    }

    componentWillEnter(callback) {
      this.onTransitionEnd = callback;
      setTimeout(() => {
        this.setState({
          style: mountedStyle,
        });
      }, 20);
    }

    componentWillLeave(callback) {
      this.onTransitionEnd = callback;
      this.setState({
        style: unmountedStyle,
      });
    }

    render() {
      return <div
        style={this.state.style}
        onTransitionEnd={this.onTransitionEnd}
      >
        <Wrapped { ...this.props } />
      </div>
    }
  }
};

ব্যবহার:

import React, { PureComponent } from 'react';

class Thing extends PureComponent {
  render() {
    return <div>
      Test!
    </div>
  }
}

export default AnimatedMount({
  unmountedStyle: {
    opacity: 0,
    transform: 'translate3d(-100px, 0, 0)',
    transition: 'opacity 250ms ease-out, transform 250ms ease-out',
  },
  mountedStyle: {
    opacity: 1,
    transform: 'translate3d(0, 0, 0)',
    transition: 'opacity 1.5s ease-out, transform 1.5s ease-out',
  },
})(Thing);

এবং অবশেষে, অন্য উপাদানটির renderপদ্ধতিতে:

return <div>
  <ReactTransitionGroup>
    <Thing />
  </ReactTransitionGroup>
</div>

4
এবং আপনি কীভাবে @ffxsam মাউন্ট / আনমাউন্ট করবেন না?

কিভাবে componentWillLeave()এবং কল করা componentWillEnter()হচ্ছে AnimatedMount?
রোকিত

আমার জন্য কাজ করে না, এখানে আমার স্যান্ডবক্স: কোডস্যান্ডবক্স.ইও
পি

15

এই পোস্টটির উপর ভিত্তি করে উপাদানটির আনমাউন্ট পর্বে দেরি করার জন্য আমার নতুন হুকস এপিআই (টাইপস্ক্রিপ্ট সহ) ব্যবহার করে আমার সমাধানটি এখানে দেওয়া হয়েছে :

function useDelayUnmount(isMounted: boolean, delayTime: number) {
    const [ shouldRender, setShouldRender ] = useState(false);

    useEffect(() => {
        let timeoutId: number;
        if (isMounted && !shouldRender) {
            setShouldRender(true);
        }
        else if(!isMounted && shouldRender) {
            timeoutId = setTimeout(
                () => setShouldRender(false), 
                delayTime
            );
        }
        return () => clearTimeout(timeoutId);
    }, [isMounted, delayTime, shouldRender]);
    return shouldRender;
}

ব্যবহার:

const Parent: React.FC = () => {
    const [ isMounted, setIsMounted ] = useState(true);
    const shouldRenderChild = useDelayUnmount(isMounted, 500);
    const mountedStyle = {opacity: 1, transition: "opacity 500ms ease-in"};
    const unmountedStyle = {opacity: 0, transition: "opacity 500ms ease-in"};

    const handleToggleClicked = () => {
        setIsMounted(!isMounted);
    }

    return (
        <>
            {shouldRenderChild && 
                <Child style={isMounted ? mountedStyle : unmountedStyle} />}
            <button onClick={handleToggleClicked}>Click me!</button>
        </>
    );
}

কোডস্যান্ডবক্স লিঙ্ক।


4
মার্জিত সমাধানটি দুর্দান্ত হবে যদি আপনি কিছু মন্তব্য যোগ করেছেন :)
ওয়েবউইউ

এছাড়াও জাভাস্ক্রিপ্টের এক্সটেনশনে ভাল কাজ করার কারণে টাইপস্ক্রিপ্টের এক্সটেনশন কেন ব্যবহার করবেন?
ওয়েবউইম্যান

এছাড়াও আপনার কনসোল ফেরত দেয় "নামস্থান নোডজেএস টাইমআউট খুঁজে পাবে না"
ওয়েবউইম্যান

4
@ ওয়েবউইম আপনার মন্তব্যের জন্য ধন্যবাদ। আমি "নোডজেএস টাইমআউট" দিয়ে আপনার রিপোর্ট করা সমস্যাটি পুনরায় তৈরি করতে পারি না, উত্তরের নীচে আমার কোডস্যান্ডবক্স লিঙ্কটি দেখুন। টাইপস্ক্রিপ্ট সম্পর্কে, আমি ব্যক্তিগতভাবে এটি জাভাস্ক্রিপ্টের মাধ্যমে ব্যবহার করতে পছন্দ করি, যদিও উভয়ই অবশ্যই কার্যকর able
ডেকেলে

10

আমি আমার কাজের সময় এই সমস্যাটির মুখোমুখি হয়েছি এবং সহজ মনে হয়েছিল, এটি আসলে প্রতিক্রিয়া নয়। একটি সাধারণ দৃশ্যে যেখানে আপনি এমন কিছু উপস্থাপন করেন:

this.state.show ? {childen} : null;

যেমন this.state.showপরিবর্তন শিশু দূরে মাউন্ট করা হয় / আনমাউন্ট ঠিক আছে।

আমি গ্রহণ করা একটি পদ্ধতির মধ্যে একটি মোড়কের উপাদান তৈরি করা Animateএবং এটির মতো ব্যবহার করা

<Animate show={this.state.show}>
  {childen}
</Animate>

this.state.showপরিবর্তন হিসাবে এখন , আমরা সহ প্রাপ পরিবর্তনগুলি বুঝতে পারি getDerivedStateFromProps(componentWillReceiveProps)এবং অ্যানিমেশন সম্পাদন করতে মধ্যবর্তী রেন্ডার পর্যায় তৈরি করতে পারি ।

একটি পর্যায় চক্র এর মতো দেখতে পারে

আমরা দিয়ে শুরু বাচ্চাদের মাউন্ট করা বা আনমাউন্ট না করা হলে স্ট্যাটিক স্টেজ

showপতাকাটির পরিবর্তনগুলি শনাক্ত করার পরে আমরা প্রিপ স্টেজে প্রবেশ করি যেখানে আমরা প্রয়োজনীয় বৈশিষ্ট্যগুলি গণনা করি heightএবং যেমন widthথেকে করি ReactDOM.findDOMNode.getBoundingClientRect()

তারপরে অ্যানিমেট স্টেটে প্রবেশের মাধ্যমে আমরা উচ্চতা, প্রস্থ এবং অস্বচ্ছতা 0 থেকে গণনা করা মানগুলিতে (বা যদি আনমাউন্টিং হয় তবে 0 তে) পরিবর্তন করতে সিএসএস রূপান্তর ব্যবহার করতে পারি।

রূপান্তর শেষে, আমরা মঞ্চে onTransitionEndফিরে আসার জন্য এপিআই ব্যবহার করি Static

পর্যায়গুলি কীভাবে সহজভাবে স্থানান্তরিত হয় সে সম্পর্কে আরও অনেক বিবরণ রয়েছে তবে এটি সামগ্রিক ধারণা হতে পারে :)

যদি কেউ আগ্রহী হন তবে আমি আমার সমাধান ভাগ করে নেওয়ার জন্য একটি প্রতিক্রিয়া লাইব্রেরি https://github.com/MingruiZhang/react-animate-mount তৈরি করেছি। যে কোনও প্রতিক্রিয়া স্বাগত :)


আপনার মতামতের জন্য ধন্যবাদ, আগে অশোধিত উত্তরের জন্য দুঃখিত। আমি আমার উত্তরে আরও বিশদ এবং একটি চিত্র যুক্ত করেছি, আশা করি এটি অন্যের পক্ষে আরও সহায়ক হতে পারে।
মিংরুই ঝাং

4
@ মিংরুইজং এটি দেখে ভাল লাগল যে আপনি মন্তব্যগুলি ইতিবাচকভাবে নিয়েছেন এবং আপনার উত্তরটি উন্নত করেছেন। এটি দেখতে খুব সতেজ হয়। ভাল কাজ.
বাগ

6

আমি মনে করি এর Transitionথেকে react-transition-groupমাউন্টিং / আনমাউন্টিং ট্র্যাক করার সম্ভবত সবচেয়ে সহজ উপায়। এটি অবিশ্বাস্যভাবে নমনীয়। আমি ব্যবহার করতে কতটা সহজ তা দেখানোর জন্য কয়েকটি ক্লাস ব্যবহার করছি তবে আপনি অবশ্যই নিজের জেএস অ্যানিমেশনগুলি addEndListenerপ্রোপ ব্যবহার করে সঠিকভাবে আঁকতে পারেন - যা জিএসএপি ব্যবহার করে আমারও অনেক ভাগ্য হয়েছে।

স্যান্ডবক্স: https://codesandbox.io/s/k9xl9mkx2o

এবং এখানে আমার কোড।

import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Transition } from "react-transition-group";
import styled from "styled-components";

const H1 = styled.h1`
  transition: 0.2s;
  /* Hidden init state */
  opacity: 0;
  transform: translateY(-10px);
  &.enter,
  &.entered {
    /* Animate in state */
    opacity: 1;
    transform: translateY(0px);
  }
  &.exit,
  &.exited {
    /* Animate out state */
    opacity: 0;
    transform: translateY(-10px);
  }
`;

const App = () => {
  const [show, changeShow] = useState(false);
  const onClick = () => {
    changeShow(prev => {
      return !prev;
    });
  };
  return (
    <div>
      <button onClick={onClick}>{show ? "Hide" : "Show"}</button>
      <Transition mountOnEnter unmountOnExit timeout={200} in={show}>
        {state => {
          let className = state;
          return <H1 className={className}>Animate me</H1>;
        }}
      </Transition>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

4
আপনি যদি স্টাইলযুক্ত উপাদানগুলি ব্যবহার করেন তবে আপনি স্টাইলযুক্ত উপাদানটির ভিতরে সমস্ত যুক্তি showপ্রপস করতে H1এবং করতে পারেন । লাইক ...animation: ${({ show }) => show ? entranceKeyframes : exitKeyframes} 300ms ease-out forwards;
এলেক্স

3

ফ্রেমর গতি

এনপিএম থেকে ফ্রেমার-মোশন ইনস্টল করুন।

import { motion, AnimatePresence } from "framer-motion"

export const MyComponent = ({ isVisible }) => (
  <AnimatePresence>
    {isVisible && (
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
      />
    )}
  </AnimatePresence>
)

1

যাঁরা প্রতিক্রিয়া-গতি বিবেচনা করছেন তাদের জন্য, যখন কোনও একক উপাদানটি মাউন্ট হয় এবং আনমাউন্টগুলি সেট আপ করতে পারা যায়।

রিঅ্যাক্ট-মোশন-ইউআই-প্যাক নামে একটি লাইব্রেরি রয়েছে যা এই প্রক্রিয়াটি শুরু করা অনেক সহজ করে তোলে। এটি প্রতিক্রিয়া-গতির চারপাশে একটি মোড়ক, যার অর্থ আপনি লাইব্রেরি থেকে সমস্ত সুবিধা পান (যেমন আপনি অ্যানিমেশনটি ব্যহত করতে সক্ষম হন, একই সাথে একাধিক আনমন্টগুলি ঘটতে পারে)।

ব্যবহার:

import Transition from 'react-motion-ui-pack'

<Transition
  enter={{ opacity: 1, translateX: 0 }}
  leave={{ opacity: 0, translateX: -100 }}
  component={false}
>
  { this.state.show &&
      <div key="hello">
        Hello
      </div>
  }
</Transition>

সন্নিবেশটির শেষের অবস্থাটি কী হওয়া উচিত তা নির্ধারণ করুন; লেভটি শৈলী যা প্রয়োগ করা হয় যখন উপাদান আনমাউন্ট করা হয়।

আপনি দেখতে পাবেন যে একবার আপনি দু'বার ইউআই প্যাকটি ব্যবহার করার পরে, রিঅ্যাক্ট-মোশন লাইব্রেরিটি আর তেমন উদ্বেগজনক হতে পারে না।


প্রকল্প আর রক্ষণাবেক্ষণ করা হয় না (2018)
মাইক্রো


1

এটি সহজেই CSSTransitionউপাদানটি ব্যবহার করে করা যেতে পারে react-transition-groupযা আপনি উল্লিখিত লাইব্রেরির মতোই। কৌতুক আপনি CSSTransition উপাদান মোড়ানো প্রয়োজন একটি শো / লুকান প্রক্রিয়া ছাড়া মত আপনি সাধারণত হবে .ie {show && <Child>}...অন্যথায় আপনি লুকিয়ে আছে অ্যানিমেশন এবং এটি কাজ করবে না। উদাহরণ:

ParentComponent.js

import React from 'react';
import {CSSTransition} from 'react-transition-group';

function ParentComponent({show}) {
return (
  <CSSTransition classes="parentComponent-child" in={show} timeout={700}>
    <ChildComponent>
  </CSSTransition>
)}


ParentComponent.css

// animate in
.parentComponent-child-enter {
  opacity: 0;
}
.parentComponent-child-enter-active {
  opacity: 1;
  transition: opacity 700ms ease-in;
}
// animate out
.parentComponent-child-exit {
  opacity: 1;
}
.parentComponent-child-exit-active {
  opacity: 0;
  transition: opacity 700ms ease-in;
}

0

এখানে আমার 2 টি: তার সমাধানের জন্য @ ডেকলেকে ধন্যবাদ। আমার সমাধান তার উপর ভিত্তি করে, এটি রাষ্ট্রীয় উপাদানগুলির সংস্করণ, সম্পূর্ণ পুনরায় ব্যবহারযোগ্য।

এখানে আমার স্যান্ডবক্স: https://codesandbox.io/s/302mkm1m

এখানে আমার স্নিপেট.জেএস:

import ReactDOM from "react-dom";
import React, { Component } from "react";
import style from  "./styles.css"; 

class Tooltip extends Component {

  state = {
    shouldRender: false,
    isMounted: true,
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.state.shouldRender !== nextState.shouldRender) {
      return true
    }
    else if (this.state.isMounted !== nextState.isMounted) {
      console.log("ismounted!")
      return true
    }
    return false
  }
  displayTooltip = () => {
    var timeoutId;
    if (this.state.isMounted && !this.state.shouldRender) {
      this.setState({ shouldRender: true });
    } else if (!this.state.isMounted && this.state.shouldRender) {
      timeoutId = setTimeout(() => this.setState({ shouldRender: false }), 500);
      () => clearTimeout(timeoutId)
    }
    return;
  }
  mountedStyle = { animation: "inAnimation 500ms ease-in" };
  unmountedStyle = { animation: "outAnimation 510ms ease-in" };

  handleToggleClicked = () => {
    console.log("in handleToggleClicked")
    this.setState((currentState) => ({
      isMounted: !currentState.isMounted
    }), this.displayTooltip());
  };

  render() {
    var { children } = this.props
    return (
      <main>
        {this.state.shouldRender && (
          <div className={style.tooltip_wrapper} >
            <h1 style={!(this.state.isMounted) ? this.mountedStyle : this.unmountedStyle}>{children}</h1>
          </div>
        )}

        <style>{`

           @keyframes inAnimation {
    0% {
      transform: scale(0.1);
      opacity: 0;
    }
    60% {
      transform: scale(1.2);
      opacity: 1;
    }
    100% {
      transform: scale(1);  
    }
  }

  @keyframes outAnimation {
    20% {
      transform: scale(1.2);
    }
    100% {
      transform: scale(0);
      opacity: 0;
    }
  }
          `}
        </style>
      </main>
    );
  }
}


class App extends Component{

  render(){
  return (
    <div className="App"> 
      <button onClick={() => this.refs.tooltipWrapper.handleToggleClicked()}>
        click here </button>
      <Tooltip
        ref="tooltipWrapper"
      >
        Here a children
      </Tooltip>
    </div>
  )};
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

0

লোডিং স্পিনার তৈরি করার সময়, আমি কীভাবে 2019 সালে এটি সমাধান করেছি তা এখানে। আমি কার্যকারী উপাদানগুলি প্রতিক্রিয়া ব্যবহার করছি।

আমার একটি পিতামাতার অ্যাপ উপাদান রয়েছে যার একটি শিশু স্পিনার উপাদান রয়েছে।

অ্যাপ্লিকেশনটির লোড হচ্ছে কিনা তা অ্যাপের স্টেট রয়েছে। অ্যাপটি লোড হওয়ার সময়, স্পিনারটি সাধারণত রেন্ডার হয়। যখন অ্যাপটি লোড হচ্ছে না ( isLoadingমিথ্যা হয়) স্পিনারটি প্রপ দিয়ে রেন্ডার করা হয় shouldUnmount

App.js :

import React, {useState} from 'react';
import Spinner from './Spinner';

const App = function() {
    const [isLoading, setIsLoading] = useState(false);

    return (
        <div className='App'>
            {isLoading ? <Spinner /> : <Spinner shouldUnmount />}
        </div>
    );
};

export default App;

লুকানো আছে বা না থাকায় স্পিনারের রাষ্ট্র রয়েছে। শুরুতে, ডিফল্ট প্রপস এবং রাজ্য সহ, স্পিনারকে সাধারণত রেন্ডার করা হয়। Spinner-fadeInক্লাসে ফেইড এটা animates। যখন স্পিনার ঠেকনা পায় shouldUnmountতা দিয়ে রেন্ডার Spinner-fadeOutপরিবর্তে বর্গ, এটা ফেইড অ্যানিমেট করা।

তবে আমিও চেয়েছিলাম বিলুপ্ত হওয়ার পরে উপাদানটি আনমাউন্ট করা উচিত।

এই মুহুর্তে আমি onAnimationEndউপরে @ প্রাণেশ-রাভির সমাধানের অনুরূপ সিন্থেটিক ইভেন্টটি প্রতিক্রিয়াটি ব্যবহার করার চেষ্টা করেছি , তবে এটি কার্যকর হয়নি। পরিবর্তে আমি setTimeoutঅ্যানিমেশনের সমান দৈর্ঘ্যে একটি বিলম্বের সাথে রাজ্যকে গোপনে সেট করতাম । স্পিনার সাথে দেরি হওয়ার পরে আপডেট হবে isHidden === trueএবং কোনও কিছুই রেন্ডার হবে না।

এখানে মূল কথাটি হ'ল পিতা-মাতা শিশুটিকে আনমাউন্ট করে না, এটি কখন আনমাউন্ট করতে হয় তা শিশুকে জানায়, এবং তার আন-মাউন্টিং ব্যবসায়ের যত্ন নেওয়ার পরে শিশু নিজেই আনমাউন্ট করে।

স্পিনার.জেএস :

import React, {useState} from 'react';
import './Spinner.css';

const Spinner = function(props) {
    const [isHidden, setIsHidden] = useState(false);

    if(isHidden) {
        return null

    } else if(props.shouldUnmount) {
        setTimeout(setIsHidden, 500, true);
        return (
            <div className='Spinner Spinner-fadeOut' />
        );

    } else {
        return (
            <div className='Spinner Spinner-fadeIn' />
        );
    }
};

export default Spinner;

স্পিনার.কম:

.Spinner {
    position: fixed;
    display: block;
    z-index: 999;
    top: 50%;
    left: 50%;
    margin: -40px 0 0 -20px;
    height: 40px;
    width: 40px;
    border: 5px solid #00000080;
    border-left-color: #bbbbbbbb;
    border-radius: 40px;
}

.Spinner-fadeIn {
    animation: 
        rotate 1s linear infinite,
        fadeIn .5s linear forwards;
}

.Spinner-fadeOut {
    animation: 
        rotate 1s linear infinite,
        fadeOut .5s linear forwards;
}

@keyframes fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
@keyframes fadeOut {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

@keyframes rotate {
    100% {
        transform: rotate(360deg);
    }
}

0

আমার একক উপাদান অ্যানিমেশনেরও খুব দরকার ছিল। আমি প্রতিক্রিয়া মোশন ব্যবহার করে ক্লান্ত হয়ে পড়েছিলাম তবে আমি এইরকম তুচ্ছ সমস্যার জন্য আমার চুলগুলি টানছিলাম .. (আমি জিনিস)। কিছু গুগল করার পরে আমি তাদের গিট রেপোতে এই পোস্টটি জুড়ে এসেছি। আশা করি এটি কারও সাহায্য করবে ..

থেকে জমা এবং ক্রেডিট । এটি এখন পর্যন্ত আমার পক্ষে কাজ করে। আমার ব্যবহারের ক্ষেত্রে লোড এবং আনলোডের ক্ষেত্রে অ্যানিমেট এবং আনমাউন্ট করার মডেল ছিল।

class Example extends React.Component {
  constructor() {
    super();
    
    this.toggle = this.toggle.bind(this);
    this.onRest = this.onRest.bind(this);

    this.state = {
      open: true,
      animating: false,
    };
  }
  
  toggle() {
    this.setState({
      open: !this.state.open,
      animating: true,
    });
  }
  
  onRest() {
    this.setState({ animating: false });
  }
  
  render() {
    const { open, animating } = this.state;
    
    return (
      <div>
        <button onClick={this.toggle}>
          Toggle
        </button>
        
        {(open || animating) && (
          <Motion
            defaultStyle={open ? { opacity: 0 } : { opacity: 1 }}
            style={open ? { opacity: spring(1) } : { opacity: spring(0) }}
            onRest={this.onRest}
          >
            {(style => (
              <div className="box" style={style} />
            ))}
          </Motion>
        )}
      </div>
    );
  }
}


0

আমি জানি এখানে প্রচুর উত্তর রয়েছে তবে আমি এখনও আমার সাধ্যের মতো এমন একটি পাইনি। আমি চাই:

  • কার্যকরী উপাদান
  • এমন একটি সমাধান যা আমার উপাদানগুলি যখন মাউন্ট করা / আনমাউন্ট করা হয় তখন সহজেই ফিড ইন / আউট করার অনুমতি দেয়।

বহু ঘন্টা বেঁধে দেওয়ার পরে, আমার একটি সমাধান রয়েছে যা আমি 90% বলতে চাই works আমি নীচের কোডে একটি মন্তব্য ব্লকে সীমাবদ্ধতা লিখেছি। আমি এখনও আরও ভাল সমাধান পছন্দ করতে চাই, তবে এখানকার অন্যান্য সমাধান সহ এটিই আমি খুঁজে পেয়েছি।

const TIMEOUT_DURATION = 80 // Just looked like best balance of silky smooth and stop delaying me.

// Wrap this around any views and they'll fade in and out when mounting /
// unmounting.  I tried using <ReactCSSTransitionGroup> and <Transition> but I
// could not get them to work.  There is one major limitation to this approach:
// If a component that's mounted inside of <Fade> has direct prop changes,
// <Fade> will think that it's a new component and unmount/mount it.  This
// means the inner component will fade out and fade in, and things like cursor
// position in forms will be reset. The solution to this is to abstract <Fade>
// into a wrapper component.

const Fade: React.FC<{}> = ({ children }) => {
  const [ className, setClassName ] = useState('fade')
  const [ newChildren, setNewChildren ] = useState(children)

  const effectDependency = Array.isArray(children) ? children : [children]

  useEffect(() => {
    setClassName('fade')

    const timerId = setTimeout(() => {
      setClassName('fade show')
      setNewChildren(children)
    }, TIMEOUT_DURATION)

    return () => {
      clearTimeout(timerId)
    }   

  }, effectDependency)

  return <Container fluid className={className + ' p-0'}>{newChildren}</Container>
}

আপনার যদি কোনও উপাদান থাকে তবে আপনি আউট / আউট ফেইড করতে চান, এটিকে <Fade>প্রাক্তনে মোড়ানো । <Fade><MyComponent/><Fade>

নোট করুন যে react-bootstrapএটি শ্রেণীর নাম এবং জন্য ব্যবহার করে <Container/>তবে উভয়ই সহজেই কাস্টম সিএসএস এবং একটি নিয়মিত পুরানো দ্বারা প্রতিস্থাপন করা যেতে পারে <div>


0

আমি যদি সরাসরি নোডটি অ্যানিমেটেড করার জন্য Velocityবা AnimeJSলাইব্রেরি ব্যবহার করি ( cssবা এর পরিবর্তে setTimeout), তবে আমি জানতে পেরেছিলাম hookযে অ্যানিমেশন স্থিতি onএবং কার্যকারিতা সরবরাহ করার জন্য আমি একটি ডিজাইন করতে পারিonToggle বন্ধ করার জন্য (উদাহরণস্বরূপ, স্লাইডাউন, বিবর্ণ))

মূলত হুকটি যা করে তা হ'ল অ্যানিমেশনটি টগল করা এবং বন্ধ করা এবং তারপরে সেই onঅনুযায়ী আপডেট করুন । সুতরাং আমরা অ্যানিমেশনের স্থিতিটি নির্ভুলভাবে পেতে পারি। এটি না করে একটি বিজ্ঞাপনের উপর জবাব দিতে হবে duration

/**
 * A hook to provide animation status.
 * @class useAnimate
 * @param {object} _                props
 * @param {async} _.animate         Promise to perform animation
 * @param {object} _.node           Dom node to animate
 * @param {bool} _.disabled         Disable animation
 * @returns {useAnimateObject}      Animate status object
 * @example
 *   const { on, onToggle } = useAnimate({
 *    animate: async () => { },
 *    node: node
 *  })
 */

import { useState, useCallback } from 'react'

const useAnimate = ({
  animate, node, disabled,
}) => {
  const [on, setOn] = useState(false)

  const onToggle = useCallback(v => {
    if (disabled) return
    if (v) setOn(true)
    animate({ node, on: v }).finally(() => {
      if (!v) setOn(false)
    })
  }, [animate, node, disabled, effect])

  return [on, onToggle]
}

export default useAnimate

ব্যবহার নিম্নলিখিত:

  const ref = useRef()
  const [on, onToggle] = useAnimate({
    animate: animateFunc,
    node: ref.current,
    disabled
  })
  const onClick = () => { onToggle(!on) }

  return (
      <div ref={ref}>
          {on && <YOUROWNCOMPONENT onClick={onClick} /> }
      </div>
  )

এবং অ্যানিমেট বাস্তবায়ন হতে পারে,

import anime from 'animejs'

const animateFunc = (params) => {
  const { node, on } = params
  const height = on ? 233 : 0
  return new Promise(resolve => {
    anime({
      targets: node,
      height,
      complete: () => { resolve() }
    }).play()
  })
}


0

আপনি রিঅ্যাক্ট সিন্থেটিক এভেন্ট ব্যবহার করতে পারেন

OnAnimationEnd বা onTransitionEnd এর মতো ইভেন্ট সহ আপনি এটি সম্পাদন করতে পারেন।

দস্তাবেজের প্রতিক্রিয়া: https://reactjs.org/docs/events.html#animation-events

কোড উদাহরণ: https://dev.to/michalczaplinski/super-easy-react-mount-unmount-animations-with-hooks-4foj


0

আপনি সর্বদা বিক্রয়ে জীবনচক্রের পদ্ধতিগুলি ব্যবহার করতে পারতেন তবে প্রতিক্রিয়া-রূপান্তর-গোষ্ঠীটি আপনি যে অ্যানিমেশনগুলি জুড়ে এসেছেন সেগুলির জন্য সবচেয়ে সুবিধাজনক লাইব্রেরি হ'ল, আপনি ব্যবহার করছেন styled-componentsবা প্লেইন সিএসএস। এটি বিশেষত কার্যকর যখন আপনি নিজের উপাদানটির মাউন্টিং এবং আনমাউন্টিং ট্র্যাক করতে এবং সেই অনুসারে অ্যানিমেশনগুলি রেন্ডার করতে চান। Transitionস্টাইলযুক্ত উপাদানগুলির সাথে ব্যবহার করুন এবং CSSTransitionআপনি যখন সরল সিএসএসের ক্লাস নাম ব্যবহার করছেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.