代码之家  ›  专栏  ›  技术社区  ›  jdog

this.props.location最终在我的组件中未定义

  •  0
  • jdog  · 技术社区  · 3 年前

    在我的reactJS应用程序中,我试图获取查询参数,但位置为空?

     useEffect(() => {
        const query = new URLSearchParams(props.location.search).get('sound');
        console.log(`location is ${props.params}`);
        console.log('about to fetch product');
    

    可能是因为在我的路由中我没有设置查询参数吗?还是因为我在本地主机上以开发模式运行?仅供参考-我只是随机添加?sound=sdfsdf到URL,方法是在浏览器中手动键入。

    更新====

    import React, { useState, useEffect, useRef } from 'react';
    import { Link } from 'react-router-dom';
    import { Row, Col, Image, ListGroup, Card, Button } from 'react-bootstrap';
    import Rating from '../components/Rating';
    import socketIOClient from 'socket.io-client';
    import axios from 'axios';
    // import Product from '../components/Product';
    import dotenv from 'dotenv';
    import { ReactMediaRecorder } from 'react-media-recorder';
    import firebase from 'firebase/app';
    import 'firebase/firestore';
    import 'firebase/storage';
    import { FaSpinner } from 'react-icons/fa';
    import qs from 'query-string';
    // import firebase from 'firebase';
    // import 'firebase/firestore';
    // import firebaseKeys from '../firebase.json';
    // import admin from 'firebase-admin';
    import Delayed from '../components/Delayed';
    import crypto from 'crypto';
    // import { CopyToClipboard } from 'react-copy-to-clipboard';
    const ENDPOINT = 'http://localhost:5000';
    
    const firebaseConfig = {
      apiKey: 'AIza_47lCzPY',
      authDomain: 'bueocorce.firebap.com',
      databaseURL: 'https://burrrce.firebaseio.com',
      projectId: 'burerce',
      storageBucket: 'burrce.appspot.com',
      messagingSenderId: '316448',
      appId: '1:1f5',
      measurementId: 'G-9N',
    };
    
    dotenv.config();
    firebase.initializeApp(firebaseConfig);
    // export const firestore = firebase.firestore();
    export const storage = firebase.storage();
    // firebase.analytics();
    
    // const FireStoreStuff = () => {
    //   const [firestore, fireStorage, setFirestore] = useState(undefined);
    
    //   useEffect(() => {
    //     firebase.initializeApp(firebaseKeys);
    //     setFirestore(firebase.firestore(), firebase.storage());
    //     // ...
    //   }, []);
    // };
    const AudioPreview = ({ stream }) => {
      const audioRef = useRef(null);
    
      useEffect(() => {
        console.log('starting audioPreview ========');
        if (stream) audioRef.current.srcObject = stream;
      }, [stream]);
    
      if (!stream) return null;
      return <audio ref={audioRef} autoPlay controls />;
    };
    
    const VideoPreview = ({ stream }) => {
      const videoRef = useRef(null);
    
      useEffect(() => {
        console.log('starting audioPreview ========');
        if (stream) videoRef.current.srcObject = stream;
      }, [stream]);
    
      if (!stream) return null;
      return <video ref={videoRef} autoPlay controls />;
    };
    
    function copy(paramid) {
      const el = document.createElement('input');
      el.value = window.location.href;
      el.value = el.value + '?sound=' + paramid;
      document.body.appendChild(el);
      el.select();
      document.execCommand('copy');
      document.body.removeChild(el);
    }
    function Controls({ status, startRecording, stopRecording, mediaBlobUrl }) {
      const [copied, setCopied] = useState(false);
      const [url, setURL] = useState('');
      async function uploadFile() {
        console.log('starting UPLOAD ========');
        const blob = await fetch(mediaBlobUrl).then((r) => r.blob());
        var id = crypto.randomBytes(16).toString('hex');
        var url = window.location.href;
        console.log(` the unique id for the url is ----> ${id}`);
        const path = `/recordings/${id}`;
        copy(id);
        setCopied(true);
        firebase
          .storage()
          .ref(path)
          .put(blob)
          .then(function (snapshot) {
            console.log('Uploaded complete');
          });
    
        storage.ref(path).getDownloadURL().then(setURL);
      }
      return (
        <Row>
          {/* <span className='uk-text-meta'>{status}</span> */}
          <button className='uk-margin-small-left' type='button' onClick={startRecording} disabled={status === 'recording'}>
            Start
          </button>
          <button className='uk-margin-small-left' type='button' onClick={stopRecording} disabled={status === 'stopped'}>
            Stop
          </button>
          <Row>
            {status === 'recording' ? (
              <FaSpinner icon='spinner' className='spinner' />
            ) : (
              <button
                className='uk-margin-small-left'
                type='button'
                onClick={uploadFile}
                disabled={status !== 'stopped'}
                hidden={status === 'idle'}
              >
                {!copied ? 'Copy link' : 'Copied!'}
              </button>
            )}
          </Row>
    
          {/* <Delayed waitBeforeShow={10000}>
            <button className='uk-margin-small-left' type='button' onClick={uploadFile} disabled={status !== 'stopped'}>
              done
            </button>
          </Delayed> */}
          {url && (
            <a className='uk-margin-small-left' href={url} target='_blank' rel='noopener noreferrer'>
              open
            </a>
          )}
        </Row>
      );
    }
    
    function RecordAudio() {
      return (
        <ReactMediaRecorder
          audio
          render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => (
            <Row>
              {status === 'recording' ? (
                <AudioPreview stream={previewStream} />
              ) : (
                <audio src={mediaBlobUrl} controls autoPlay />
              )}
              <Controls
                status={status}
                startRecording={startRecording}
                stopRecording={stopRecording}
                mediaBlobUrl={mediaBlobUrl}
              />
            </Row>
          )}
        />
      );
    }
    
    function RecordVideo() {
      return (
        <ReactMediaRecorder
          video
          render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => (
            <Row>
              {status === 'recording' ? (
                <VideoPreview stream={previewStream} />
              ) : (
                <video src={mediaBlobUrl} controls autoPlay />
              )}
              <Controls
                status={status}
                startRecording={startRecording}
                stopRecording={stopRecording}
                mediaBlobUrl={mediaBlobUrl}
              />
            </Row>
          )}
        />
      );
    }
    
    // function RecordScreen() {
    //   return (
    //     <ReactMediaRecorder
    //       screen
    //       render={({ status, startRecording, stopRecording, mediaBlobUrl }) => (
    //         <div>
    //           <video src={mediaBlobUrl} controls autoPlay />
    //           <Controls
    //             status={status}
    //             startRecording={startRecording}
    //             stopRecording={stopRecording}
    //             mediaBlobUrl={mediaBlobUrl}
    //           />
    //         </div>
    //       )}
    //     />
    //   );
    // }
    
    // function handleClick(num) {
    //   this.setState(num);
    // }
    
    const ProductScreen = ({ match }) => {
      const [product, setProduct] = useState({});
      // const query = null;
    
      // const query = URLSearchParams(props.location.search).get('sound');
      // console.log(this.match.location.search);
      // if (match && match.location && match.location.search) {
      //   query = qs.parse(match.location.search, {
      //     ignoreQueryPrefix: true,
      //   });
      // }
    
      useEffect(() => {
        const query = new URLSearchParams(match.location).get('sound');
        console.log(`location is ${match.params}`);
        console.log('about to fetch product');
        const fetchProduct = async () => {
          console.log('Below is the id param waht the fuck is it?');
          console.log(match.params.id);
          const { data } = await axios.get(`http://localhost:5000/api/products/${match.params.id}`);
    
          setProduct(data);
        };
        fetchProduct();
        const socket = socketIOClient(ENDPOINT);
        socket.on('status-update', function (call) {
          const stext = document.getElementById('statusText');
          stext.innerText = call;
        });
    
        // CLEAN UP THE EFFECT
        // return () => socket.disconnect();
      }, [match]);
      const [state, setState] = useState(0);
      return (
        <>
          <script src='https://www.gstatic.com/firebasejs/8.7.1/firebase-app.js'></script>
    
          <script src='https://www.gstatic.com/firebasejs/8.7.1/firebase-analytics.js'></script>
          <Link className='btn btn-light my-3' to='/'>
            Go Back
          </Link>
          <Row>
            <Col md={6}>
              <Image src={product.image} alt={product.name} fluid />
            </Col>
            <Col md={3}>
              <ListGroup variant='flush'>
                <ListGroup.Item>
                  <h3>{product.name}</h3>
                </ListGroup.Item>
                <ListGroup.Item>
                  <Rating value={product.rating} text={`${product.numReviews} reviews`} />
                </ListGroup.Item>
                <ListGroup.Item>Price : {product.price}</ListGroup.Item>
                <ListGroup.Item>Description : {product.description}</ListGroup.Item>
              </ListGroup>
            </Col>
            <Col md={3}>
              <Card>
                <ListGroup variant='flush'>
                  <ListGroup.Item>
                    <Row>
                      <Col>Price: </Col>
                      <Col>
                        <strong>${product.price}</strong>
                      </Col>
                    </Row>
                  </ListGroup.Item>
                </ListGroup>
                <ListGroup variant='flush'>
                  <ListGroup.Item>
                    <Row>
                      <Col>Status: </Col>
                      <Col>{product.countInStock > 0 ? 'In Stock' : 'Out of Stock'}</Col>
                    </Row>
                  </ListGroup.Item>
                  <ListGroup.Item>
                    <Button
                      //   onClick={addToCartHandler}
                      className='btn-block w-100'
                      type='button'
                      disabled={product.countInStock === 0}
                    >
                      Add To Cart
                    </Button>
                  </ListGroup.Item>
                  <ListGroup.Item>
                    <Row>
                      <Col>Copy Status: </Col>
                      <Col>
                        <h2 id='statusText'>Share</h2>
                        <button type='button' onClick={() => setState(1)}>
                          audio
                        </button>
                        <button type='button' onClick={() => setState(2)}>
                          video
                        </button>
                        {/* <button type="button" onClick={() => setState(3)}>
            screen
          </button> */}
                        {state === 1 && <RecordAudio />}
                        {state === 2 && <RecordVideo />}
                        {/* {state === 3 && <RecordScreen />} */}
                      </Col>
                    </Row>
                  </ListGroup.Item>
                </ListGroup>
              </Card>
            </Col>
          </Row>
        </>
      );
    };
    
    export default ProductScreen;
    
    0 回复  |  直到 3 年前
        1
  •  2
  •   Nithish    3 年前

    问题

    这个 match 道具没有 location 所有物

    匹配对象包含有关如何 <Route path> 匹配 URL.match对象包含以下属性:

    • params-(object)从与路径的动态段相对应的URL解析的键/值对
    • isExact-(布尔值)true,如果整个URL匹配(没有尾随字符)
    • path-(字符串)用于匹配的路径模式。适用于构建嵌套 <Route> s
    • url-(字符串)url的匹配部分。用于构建嵌套 <Link> s

    这个 ProductScreen 只是在破坏 match 道具

    const ProductScreen = ({ match }) => { ....
    

    解决方案

    破坏 location 道具并访问 search 所有物

    const ProductScreen = ({ location, match }) => {
      const [product, setProduct] = useState({});
      
      const query = new URLSearchParams(location.search).get('sound');
      console.log(location.search);