اذهب إلى المحتوى

السؤال

نشر

مرحبا لدي صفحة تحتوي على form للاضافة وعند زيارتها يظهر لي الخطأ window is not defined لكنه لا يشير لشيء معين يسبب المشكلة وهذا هو مكون الصفحة 

import React, { useState } from 'react';
import {
  Flex,
  Box,
  FormControl,
  FormLabel,
  Input,
  Textarea,
  Stack,
  Button,
  Heading,
  FormErrorMessage,
  useColorModeValue,
  useToast,
} from '@chakra-ui/react';
import axios from 'axios';
import { useForm } from 'react-hook-form';
import { useRouter } from 'next/router';

import {Editor} from "react-draft-wysiwyg"
import { EditorState, convertToRaw } from 'draft-js';

import draftToHtml from 'draftjs-to-html';
// import htmlToDraft from 'html-to-draftjs';
import 'node_modules/react-draft-wysiwyg/dist/react-draft-wysiwyg.css';

export default function EditorConvertToHTML() {
  const router = useRouter();
  const toast = useToast();
  const [state, setState] = useState({
    editorState: EditorState.createEmpty(),
  });

  const onEditorStateChange = (editorState) => {
    setState({
      editorState,
    });
  };

  const {
    handleSubmit,
    register,
    formState: { errors, isSubmitting },
  } = useForm();

  async function onSubmit(values, e) {
    e.preventDefault();
    console.log({
      ...values,
      content: draftToHtml(convertToRaw(state.editorState.getCurrentContent())),
    });

    try {
      const res = await axios.post(`${process.env.NEXT_PUBLIC_API}/article/add`, {
        ...values,
        content: draftToHtml(convertToRaw(state.editorState.getCurrentContent())),
      });

      router.push('/');
    } catch (error) {
      console.log(error);
      toast({
        title: 'فشل في عملية الارسال',
        status: 'error',
        duration: 9000,
        // isClosable: true,
      });
    }
  }

  //title
  //description
  //content
  //imageUrl

  return (
    <Box>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Box p="4" w="50%" mb="8" bg="white">
          <FormControl id="email" isInvalid={errors.title}>
            <FormLabel>العنوان</FormLabel>
            <Input
              {...register('title', {
                required: 'هذا مطلوب',
              })}
            />
            <FormErrorMessage>{errors.title && errors.title.message}</FormErrorMessage>
          </FormControl>
          <FormControl id="email" isInvalid={errors.description}>
            <FormLabel>وصف</FormLabel>
            <Textarea
              {...register('description', {
                required: 'هذا مطلوب',
              })}
            />
            <FormErrorMessage>{errors.description && errors.description.message}</FormErrorMessage>
          </FormControl>
          <FormControl id="email" isInvalid={errors.imageUrl}>
            <FormLabel>الصورة</FormLabel>
            <Input
              {...register('imageUrl', {
                required: 'هذا مطلوب',
              })}
            />
            <FormErrorMessage>{errors.imageUrl && errors.imageUrl.message}</FormErrorMessage>
          </FormControl>
        </Box>
        <Box shadow="md" dir="ltr" w="50%" mb="8" bg="white">
          <Editor
            editorState={state.editorState}
            wrapperClassName="demo-wrapper"
            editorClassName="demo-editor"
            onEditorStateChange={onEditorStateChange}
          />
        </Box>
        <Box w="50%" bg="white">
          <Textarea
            disabled
            value={draftToHtml(convertToRaw(state.editorState.getCurrentContent()))}
          />
        </Box>
        <Button
         
          type="submit"
          isLoading={isSubmitting}
          isDisabled={isSubmitting}
          bg={'blue.400'}
          color={'white'}
          _hover={{
            bg: 'blue.500',
          }}
        >
          سجل الدخول
        </Button>
      </form>
    </Box>
  );
}

 

Recommended Posts

  • 0
نشر

هذه المشكلة تظهر عند عمل import لل draft.js عند العمل بnext js

سبب الخطأ هو ان next jsتعمل على كلاً من العميل والخادم , وال window لا يعمل إلا عند العميل, فعند تشغيل الكود عند الخادم لا يعمل بشكل جيد , والحل أن تقوم بعمل import بعد أن يتم تحميل الصفحة, أى في الدالة componentDidMount او في الuseEffect hook إن كنت تستخدم الfunctional components, نقوم أولا بتعريف متغير يحمل component فارغ لحجز الdraft Editor

let Editor = () => <></>;

ثم نقوم بعمل state لل Editor

[editorState, setEditorState] = useState(); 

بعدها نقوم بإستدعاء draftووضع قيمتها في المتغير الفارغ في الuseEffect

useEffect(() => { 
  Editor = require("react-draft-wysiwyg").Editor; 
  setEditorState(true) 
},[]);

ومن ثم عند عمل returnلل component ضع شرط اولاً ان يكون ال EditorState معرفة 

  • 0
نشر

كما شرح شرف الدين أنه المشكلة أن الكائن window متوفر فقط في المتصفح لذلك ينبغي عليك استخدامه في ال  الدالة componentDidMount او في الuseEffect hook أو ببساطة يمكنك استخدلم ال dynamic import مع ظبط الخسار srr ل false  فقط وتستخدم نفس الكود بدون تغيير أو الحاجة للدالة componentDidMount او  الuseEffect hook كما في المثال التالي

// components/Scroll.js

function onScroll() {
  console.log("scroll!");
}

window.addEventListener("scroll", onScroll);

export default function Scroll() {
  return null;
}
// pages/index.js

import dynamic from "next/dynamic";

const Scroll = dynamic(
  () => {
    return import("../components/Scroll");
  },
  { ssr: false }
);

export default function Home() {
  return (
    <div style={{ minHeight: "1000px" }}>
      <h1>Home</h1>
      <Scroll />
    </div>
  );
}

 

  • 1
نشر

المشكلة تكمن في التحديد في هذه المكتبة 

import {Editor} from "react-draft-wysiwyg"

الشيفرة الداخلية لهذه المكتبة تستخدم window وبالتالي عند يشتغل المكون في جانب الخادم ستحمل هذه الشيفرة ويحدث الخطأ هناك نظرا لأن window لا تتواجد في جانب الخادم والحل ببساطة لهذه المكتبة أو كل المكتبات التي تعول على window هو بعدم السماح للمكتبات بالتحميل في جانب الخادم عن طريق الاستيراد الديناميكي مع اضافة خيار تعطيل الاستيراد في server side rendering هذا سيصلح المشكلة

const Editor = dynamic(
  () => {
    return import('react-draft-wysiwyg').then((mod) => mod.Editor);
  },
  { ssr: false }
);

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...