reactjs - 如何在 nextjs 中使用 react-bodymovin

标签 reactjs animation next.js bodymovin

react-bodymovin 非常适合我的 reactjs 应用程序,但是当迁移到 nextjs 时,它不起作用。我收到以下错误:

ReferenceError: window is not defined
    at Object.<anonymous> (/Users/xyz/work/web/dict/next/node_modules/bodymovin/build/player/bodymovin_light.min.js:1:226)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/xyz/work/web/dict/next/node_modules/react-bodymovin/lib/ReactBodymovin.js:2:17)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)

只需导入库 bodymovin,就会导致以上所有情况

import React, { Component } from 'react';
import Router from 'next/router';
import Layout from '../components/Layout';
import SuggestionList from '../components/SuggestionList';
import dict from '../api/dict';
import ReactBodymovin from 'react-bodymovin';

如果我按以下方式禁用,它会起作用

import React, { Component } from 'react';
import Router from 'next/router';
import Layout from '../components/Layout';
import SuggestionList from '../components/SuggestionList';
import dict from '../api/dict';
//import ReactBodymovin from 'react-bodymovin';

最佳答案

您的问题很可能是由于使用没有服务器端渲染错误修复的旧版本的 bodymovin/lottie,因此找不到窗口,因为它在服务器端编译时不存在。

此处提供更多信息:https://github.com/zeit/next.js/wiki/FAQ#i-use-a-library-which-throws-window-is-undefined

解决这个问题:

1) 将正确的第 3 方添加到依赖项中: "react-lottie": "^1.2.3"

Lottie Web给出了a SSR bugfixreact-lottie应该更新以避免窗口问题。

https://github.com/chenqingspring/react-lottie/issues/17

2) 将以下文件放入./pages/lottie.js

import React from "react";
import Lottie from "react-lottie";
import * as animationData from "../animations/loading-spinner-black.json";

export default class LottieControl extends React.Component {
constructor(props) {
    super(props);
    this.state = { isStopped: false, isPaused: false };
}

render() {
    const buttonStyle = {
    display: "block",
    margin: "10px auto"
    };

    console.log(animationData);

    const defaultOptions = {
    loop: true,
    autoplay: true,
    animationData: animationData.default,
    rendererSettings: {
        preserveAspectRatio: "xMidYMid slice"
    }
    };

    return (
    <div>
        <Lottie
        options={defaultOptions}
        height={400}
        width={400}
        isStopped={this.state.isStopped}
        isPaused={this.state.isPaused}
        />
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isStopped: true })}
        >
        stop
        </button>
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isStopped: false })}
        >
        play
        </button>
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isPaused: !this.state.isPaused })}
        >
        pause
        </button>
    </div>
    );
}
}

3) 将以下文件放入./animations/loading-spinner-black.json

{"v":"5.1.8","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":100,"h":100,"nm":"Spinner","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"spinner Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[160,284,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,19.812],[19.882,0],[0,-19.882],[-19.882,0]],"o":[[0,-19.882],[-19.882,0],[0,19.882],[19.882,0]],"v":[[36,0],[0,-36],[-36,0],[0,36]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":29,"s":[0],"e":[0]},{"t":51.0000020772726}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":20,"s":[100],"e":[1]},{"t":60.0000024438501}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[160,284],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[-90],"e":[270]},{"t":59.0000024031193}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60.0000024438501,"st":0,"bm":0}],"markers":[]}

4) "npm run dev"并转到 http://localhost:3000/lottie你应该会看到一个带有控件的黑色旋转动画

或者,如果您不能更改依赖项并通过 process.cient 强制使用客户端代码执行,则可以忽略上述内容。查看更多详情 here .

希望这对您有所帮助。如果您还有其他问题,请告诉我,如果需要,我可以举一个实例。

关于reactjs - 如何在 nextjs 中使用 react-bodymovin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54395511/

相关文章:

reactjs - TypeScript 提示有条件地分配类 : JSX element type 'TouchableComponent' does not have any construct or call signatures

animation - CSS 动画速记

javascript - 从网络浏览器外部停止 HTML5 动画

javascript - Google charts - 阶梯式图表动画

reactjs - Next js 中的嵌套路由

javascript - 匹配 URL 的正则表达式 - 字符串末尾的数字,但也匹配字符串开头的字符

javascript - 如何从 Jest 测试套件中排除 CSS 模块文件?

reactjs - 查找react-native使用哪个版本的reactJS?

java - WebSockets 请求中请求的资源上不存在 'Access-Control-Allow-Origin' header

next.js - 我可以让 Next.Js 在构建期间排除 .babelrc 吗?